1. 程式人生 > >2017.10.25 模擬賽

2017.10.25 模擬賽

lose getchar() 前綴 query job fin argc apt it!

題目鏈接

T1

貪心或二分答案

技術分享
#include <algorithm>
#include <cstring>
#include <cctype>
#include <cstdio>
#define N 100005

using namespace std;
int n;
struct node
{
    int Ti,Si;
    bool operator<(node a)const
    {
        return Si<a.Si;
    }
}Task[N];
int main()
{
    freopen(
"manage.in","r",stdin); freopen("manage.out","w",stdout); scanf("%d",&n); for(int i=1;i<=n;i++) scanf("%d%d",&Task[i].Ti,&Task[i].Si); sort(Task+1,Task+n+1); bool flag=false; int tim=0,ans=0x3f3f3f3f; for(int i=1;i<=n;i++) { if(tim+Task[i].Ti>Task[i].Si) { flag
=true; break; } tim+=Task[i].Ti; ans=min(ans,Task[i].Si-tim); } if(flag) puts("-1"); else printf("%d\n",ans); fclose(stdin); fclose(stdout); return 0; }
貪心 技術分享
#include <algorithm>
#include <cstdio>

inline void read(int
&x) { x=0; register char ch=getchar(); for(; ch>9||ch<0; ) ch=getchar(); for(; ch>=0&&ch<=9; ch=getchar()) x=x*10+ch-0; } const int N(100005); struct Work { int t,s; bool operator < (const Work&x)const { if(s==x.s) return t<x.t; return s<x.s; } }job[N]; int ans=-1,L,R,Mid,n; inline bool check(int x) { for(int i=1; i<=n; ++i) { if(x+job[i].t>job[i].s) return 0; x+=job[i].t; } return 1; } int Presist() { freopen("manage.in","r",stdin); freopen("manage.out","w",stdout); read(n); for(int t,i=1; i<=n; ++i) read(job[i].t),read(job[i].s); std::sort(job+1,job+n+1); for(R=job[1].s-job[1].t+1; L<=R; ) { Mid=L+R>>1; if(check(Mid)) { ans=Mid; L=Mid+1; } else R=Mid-1; } printf("%d\n",ans); return 0; } int Aptal=Presist(); int main(int argc,char**argv){;}
二分

T2

sum[i]為前綴和,num[i]為i顏色的數量
那麽i這種顏色對答案的貢獻就是C(sum[i]-1,num[i]-1)%mod;
因為i的最後一個不能放到i+1最後一個的前面,所以要減一
分步乘法原理。

技術分享
#include <cstdio>
#include <cctype>
#define Mod 998244353
#define N 1000070
typedef long long LL;
inline void read(LL &x)
{
    bool f=0;register char ch=getchar();
    for(x=0;!isdigit(ch);ch=getchar()) if(ch==-) f=1;
    for(;isdigit(ch);x=x*10+ch-0,ch=getchar());
    x=f?-x:x;
}
LL n,ans=1,num[N],sum[N],f[N],fac[N],inv[N];
void init()
{
    f[0]=inv[0]=fac[0]=f[1]=inv[1]=fac[1]=1;
    for(LL i=2;i<=N;++i)
    {
        fac[i]=(fac[i-1]%Mod*i%Mod)%Mod;
        f[i]=(Mod-Mod/i)*f[Mod%i]%Mod;
        inv[i]=(inv[i-1]%Mod*f[i]%Mod)%Mod;
    }
}
LL C(LL m,LL n)
{
    if(n>m) return 1;
    return fac[m]%Mod*inv[n]%Mod*inv[m-n]%Mod;
}
void print(LL ans)
{
    if(ans/10) print(ans/10);
    putchar(ans%10+0);
}
int main(int argc,char *argv[])
{
    freopen("qiang.in","r",stdin);
    freopen("qiang.out","w",stdout);
    read(n);
    for(LL i=1;i<=n;++i) read(num[i]),sum[i]=sum[i-1]+num[i];
    init();
    for(LL i=2;i<=n;++i) ans=(ans%Mod*C(sum[i]-1,num[i]-1)%Mod)%Mod;
    print(ans);
    fclose(stdin); fclose(stdout);
    return 0;
}
std

T3

題目來源 codechef NOV14.FNCS Chef and Churu
80分 黔驢技窮了 比著std寫的 std不知為何 0分啊我也很絕望。
對於每個fi,可以直接使用樹狀數組求出。
所以我們可以使用分塊,中間的直接用塊的答案,邊上的用樹狀數組。
首先我們進行預處理,記錄第i塊中每個編號的個數,這裏用前綴和,並求出每個塊的和。
對於修改操作1 x y,我們要維護樹狀數組和塊狀數組。
樹狀數組:直接維護。
塊狀數組:找到每個塊中x的個數,這塊的sum加上x*(y-a[x])。
最後把a[x]賦成y。
對於查詢操作2 x y。
中間的塊我們直接用塊狀數組的答案,O(√n)。
邊上的兩塊我們用樹狀數組暴力求所有的f[i],O(√n log n)。
所以總的時間復雜度為O(n √n log n)。

技術分享
#include <algorithm>
#include <iostream>
#include <cstdio>
#include <cctype>
#define N 100005

using namespace std;
typedef long long LL;
inline void read(LL &x)
{
    bool f=0;register char ch=getchar();
    for(x=0;!isdigit(ch);ch=getchar()) if(ch==-) f=1;
    for(;isdigit(ch);x=x*10+ch-0,ch=getchar());
    x=f?-x:x;
}
LL tag[N],val[N<<2|1];
int n,q,a[N],x[N],y[N],cnt[N<<2|1],mid[N<<2|1];
struct node
{
    int x,y,id;
    bool operator<(node a)const
    {
        if(x==a.x) return y<a.y;
        else return x<a.x;
    }
}b[N];
inline int lowbit(int &x) {return x&(-x);}
inline void add(int x,int y) {for(;x<=n;x+=lowbit(x)) tag[x]+=y;}
inline LL ask(int x)
{
    LL ret=0;
    for(;x;x-=lowbit(x)) ret+=tag[x];
    return ret;
}
void build(int k,int l,int r)
{
    if(l==r) {val[k]=ask(y[l])-ask(x[l]-1);return;}
    mid[k]=(l+r)>>1;
    build(k<<1,l,mid[k]);
    build(k<<1|1,mid[k]+1,r);
    val[k]=val[k<<1]+val[k<<1|1];
}
void modify(int k,int l,int r,int t)
{
    if(l==r) {val[k]=ask(y[l])-ask(x[l]-1);return;}
    if(t<=mid[k]) modify(k<<1,l,mid[k],t);
    else modify(k<<1|1,mid[k]+1,r,t);
    val[k]=val[k<<1]+val[k<<1|1];
}
LL query(int k,int l,int r,int x,int y)
{
    if(l>=x&&r<=y) return val[k];
    LL ret=0;
    if(x<=mid[k]) ret+=query(k<<1,l,mid[k],x,y);
    if(y>mid[k]) ret+=query(k<<1|1,mid[k]+1,r,x,y);
    return ret;
}
int main(int argc,char *argv[])
{
    freopen("sum.in","r",stdin);
    freopen("sum.out","w",stdout);
    scanf("%d",&n);
    for(int i=1;i<=n;++i) scanf("%d",&a[i]),add(i,a[i]);
    for(int i=1;i<=n;++i)
    {
        scanf("%d%d",&x[i],&y[i]);
        b[i].x=x[i];
        b[i].y=y[i];
        b[i].id=i;
    }
    build(1,1,n);
    sort(b+1,b+1+n);
    scanf("%d",&q);
    for(int opt,l,r;q--;)
    {
        scanf("%d%d%d",&opt,&l,&r);
        if(opt==1)
        {
            add(l,r-a[l]),a[l]=r;
            for(int i=1;i<=n;++i)
            {
                if(b[i].x<=l) modify(1,1,n,b[i].id);
                else break;
            }
        }
        else cout<<query(1,1,n,l,r)<<"\n";
    }
    fclose(stdin); fclose(stdout);
    return 0;
}
考場20分代碼 技術分享
#include<iostream>
#include<cstdio>
#include<cstring>
#include<cmath>

#define ll long long
#define N 100007
#define S 400

using namespace std;
int n,m,unit,num;
int fl[N],fr[N],a[N];
int cnt[S][N];
ll ta[N],sumb[S];

inline int read()
{
    int x=0,f=1;char c=getchar();
    while(c>‘9‘||c<‘0‘){if(c==‘-‘)f=-1;c=getchar();}
    while(c>=‘0‘&&c<=‘9‘){x=x*10+c-‘0‘;c=getchar();}
    return x*f;
}

inline int lowbit(int x){return x&-x;}

inline void ins(int i,int add)
{
    for(;i<=n;i+=lowbit(i)) ta[i]+=add;
}

inline void update(int x,int y)
{
    ins(x,y-a[x]);
    for(int i=1;i<=num;i++) sumb[i]+=(ll)cnt[i][x]*(y-a[x]);
    a[x]=y;
}

inline ll getsum(int i)
{
    ll sum=0;
    for(;i;i-=lowbit(i)) sum+=ta[i];
    return sum;
}

ll query(int l,int r)
{
    int lblock=(l-1)/unit+1,rblock=(r-1)/unit+1;ll sum=0;
    if(lblock==rblock)
      for(int i=l;i<=r;i++)
        sum+=getsum(fr[i])-getsum(fl[i]-1);
    else
    {
        for(int i=lblock+1;i<=rblock-1;i++) sum+=sumb[i];
        for(int i=l;i<=lblock*unit;i++) sum+=getsum(fr[i])-getsum(fl[i]-1);
        for(int i=(rblock-1)*unit+1;i<=r;i++) sum+=getsum(fr[i])-getsum(fl[i]-1);
    }return sum;
}

int main()
{
    freopen("sum.in","r",stdin);
    freopen("sum.out","w",stdout);
    
    n=read();
    for(int i=1;i<=n;i++) a[i]=read();
    for(int i=1;i<=n;i++) fl[i]=read(),fr[i]=read();
    for(int i=1;i<=n;i++) ins(i,a[i]);
    
    int nowblock=0;
    unit=(int)sqrt(n),num=unit+(unit*unit!=n);
    for(int i=1;i<=n;i++)
    {
        if(i%unit==1) nowblock++;
        cnt[nowblock][fl[i]]++;
        cnt[nowblock][fr[i]+1]--;
    }
    for(int i=1;i<=num;i++)
      for(int j=1;j<=n;j++)
      {
            cnt[i][j]+=cnt[i][j-1];
            sumb[i]+=(ll) cnt[i][j]*a[j];
      }
      
    int k,x,y;
    m=read();
    for(int i=1;i<=m;i++)
    {
        k=read();x=read();y=read();
        if(k==1) update(x,y);
        else printf("%I64d\n",query(x,y));
    }
    fclose(stdin);fclose(stdout);
    return 0;
}
std

2017.10.25 模擬賽