• The 2020 ICPC Asia Macau Regional Contest


    题解:

    https://files.cnblogs.com/files/clrs97/2020icpc-macau-analyze.zip

    Code:

    A. Accelerator

    #include<cstdio>
    #include<vector>
    using namespace std;
    typedef long long ll;
    typedef vector<int>V;
    const int N=1048576,K=19,P=998244353,G=3;
    int T,n,m,i,k,a[N],fac[N+10],A[N+10],B[N+10],g[K+1],ng[K+1],inv[N+10];
    inline int po(int a,int b){int t=1;for(;b;b>>=1,a=(ll)a*a%P)if(b&1)t=(ll)t*a%P;return t;}
    inline void NTT(int*a,int n,int t){
      for(int i=1,j=0;i<n-1;i++){
        for(int s=n;j^=s>>=1,~j&s;);
        if(i<j){int k=a[i];a[i]=a[j];a[j]=k;}
      }
      for(int d=0;(1<<d)<n;d++){
        int m=1<<d,m2=m<<1,_w=t==1?g[d]:ng[d];
        for(int i=0;i<n;i+=m2)for(int w=1,j=0;j<m;j++){
          int&A=a[i+j+m],&B=a[i+j],t=(ll)w*A%P;
          A=B-t;if(A<0)A+=P;
          B=B+t;if(B>=P)B-=P;
          w=(ll)w*_w%P;
        }
      }
      if(t==-1)for(int i=0,j=inv[n];i<n;i++)a[i]=(ll)a[i]*j%P;
    }
    V solve(int l,int r){
      if(l==r){
        V t;
        t.push_back(1);
        t.push_back(a[l]);
        return t;
      }
      int mid=(l+r)>>1,k=1,i;
      V a=solve(l,mid),b=solve(mid+1,r),t;
      for(;k<=r-l+1;k<<=1);
      for(i=0;i<=mid-l+1;i++)A[i]=a[i];
      for(i=mid-l+2;i<k;i++)A[i]=0;
      for(i=0;i<=r-mid;i++)B[i]=b[i];
      for(i=r-mid+1;i<k;i++)B[i]=0;
      NTT(A,k,1),NTT(B,k,1);
      for(i=0;i<k;i++)A[i]=1LL*A[i]*B[i]%P;
      NTT(A,k,-1);
      for(i=0;i<=r-l+1;i++)t.push_back(A[i]);
      return t;
    }
    int main(){
      for(g[K]=po(G,(P-1)/N),ng[K]=po(g[K],P-2),i=K-1;~i;i--)g[i]=(ll)g[i+1]*g[i+1]%P,ng[i]=(ll)ng[i+1]*ng[i+1]%P;
      for(inv[1]=1,i=2;i<N;i++)inv[i]=(ll)(P-inv[P%i])*(P/i)%P;
      for(fac[0]=i=1;i<N;i++)fac[i]=1LL*fac[i-1]*i%P;
      scanf("%d",&T);
      while(T--){
        scanf("%d",&n);
        for(i=1;i<=n;i++)scanf("%d",&a[i]);
        V t=solve(1,n);
        int ans=0;
        for(i=1;i<=n;i++)ans=(1LL*t[i]*fac[i]%P*fac[n-i]+ans)%P;
        ans=1LL*ans*po(fac[n],P-2)%P;
        printf("%d\n",ans);
      }
    }
    

      

    B. Boring Problem

    #include<cstdio>
    #include<algorithm>
    using namespace std;
    const int N=105,M=10005,K=26,P=1000000007;
    char s[M];
    int n,m,S,i,j,k,deg,x,y,A,B,each[K],ieach[K];
    int tot,son[M][K],dep[M],fail[M],g[M][K],q[M];
    int cnt,ce,f[M][N],a[N][N],ans[N],e[M];
    inline int po(int a,int b){int t=1;for(;b;b>>=1,a=1LL*a*a%P)if(b&1)t=1LL*t*a%P;return t;}
    inline void ins(){
      scanf("%s",s+1);
      for(int i=1,x=0,w;i<=m;i++){
        if(!son[x][w=s[i]-'a'])son[x][w]=++tot;
        x=son[x][w];
        dep[x]=i;
      }
    }
    void make(){
      int h=1,t=0,i,j,x;
      fail[0]=-1;
      for(i=0;i<=tot;i++)for(j=0;j<S;j++)g[i][j]=son[i][j];
      for(i=0;i<S;i++)if(g[0][i])q[++t]=g[0][i];
      while(h<=t){
        x=q[h++];
        for(i=0;i<S;i++){
          if(g[x][i])fail[g[x][i]]=g[fail[x]][i],q[++t]=g[x][i];
          else g[x][i]=g[fail[x]][i];
        }
      }
    }
    void gauss(){
      int i,j,k,inv,t;
      for(i=1;i<=cnt;i++)for(j=1;j<=cnt;j++)a[i][j]=(a[i][j]%P+P)%P;
      for(i=1;i<=cnt;i++)a[i][0]=(P-a[i][0])%P;
      for(i=1;i<=cnt;i++){
        for(j=i;j<=cnt;j++)if(a[j][i])break;
        for(k=0;k<=cnt;k++)swap(a[i][k],a[j][k]);
        inv=po(a[i][i],P-2);
        for(j=i+1;j<=cnt;j++){
          t=1LL*a[j][i]*inv%P;
          for(k=0;k<=cnt;k++)a[j][k]=(a[j][k]-1LL*t*a[i][k])%P;
        }
      }
      for(i=cnt;i;i--){
        t=a[i][0];
        for(j=cnt;j>i;j--)t=(t-1LL*a[i][j]*ans[j])%P;
        ans[i]=1LL*t*po(a[i][i],P-2)%P;
      }
    }
    int main(){
      scanf("%d%d%d",&n,&m,&S);
      for(i=0;i<S;i++){
        scanf("%d",&x);
        each[i]=1LL*x*po(100,P-2)%P;
        ieach[i]=po(each[i],P-2);
      }
      while(n--)ins();
      make();
      cnt=1;
      f[0][1]=1;
      for(i=0;i<=tot;i++){
        deg=0;
        for(j=0;j<S;j++)if(son[i][j]){
          deg++;
          if(deg>1){
            cnt++;
            f[son[i][j]][cnt]=1;
          }
        }
      }
      for(i=0;i<=tot;i++){
        x=q[i];
        deg=0;
        for(j=0;j<S;j++)if(son[x][j]){
          deg++;
          if(deg==1)A=son[x][j],B=j;
        }
        if(deg){
          //e[x]=sum(e[g[x][i]]*each[i])+1
          //e[A]*each[B]=e[x]-1-sum(e[g[x]][i]*each[i])
          for(j=0;j<=cnt;j++)f[A][j]=f[x][j];
          f[A][0]--;
          for(j=0;j<S;j++)if(j!=B){
            y=g[x][j];
            for(k=0;k<=cnt;k++)f[A][k]=(f[A][k]-1LL*f[y][k]*each[j])%P;
          }
          for(j=0;j<=cnt;j++)f[A][j]=1LL*f[A][j]*ieach[B]%P;
        }
      }
      for(i=0;i<=tot;i++)if(dep[i]==m){
        ce++;
        for(j=0;j<=cnt;j++)a[ce][j]=f[i][j];
      }
      gauss();
      for(i=0;i<=tot;i++){
        k=f[i][0];
        for(j=1;j<=cnt;j++)k=(k+1LL*f[i][j]*ans[j])%P;
        e[i]=(k%P+P)%P;
      }
      scanf("%s",s);
      for(x=i=0;s[i];i++){
        if(dep[x]<m)x=g[x][s[i]-'a'];
        printf("%d\n",e[x]+i+1);
      }
    }
    

      

    C. Club Assignment

    #include<cstdio>
    #include<algorithm>
    using namespace std;
    const int N=100010,M=N*31,K=29;
    int Case,n,i,q[N],_q[N],son[M][2],val[M],tot,g[N],v[N<<1],nxt[N<<1],ed;
    int c0,c1,p0[N],p1[N],col[N];
    int a[N],ans;
    inline void add(int x,int y){
      v[++ed]=y;nxt[ed]=g[x];g[x]=ed;
      v[++ed]=x;nxt[ed]=g[y];g[y]=ed;
    }
    inline void ins(int p,int t){
      int o=K,x=0;
      for(;~o;o--){
        int w=p>>o&1;
        if(!son[x][w])son[x][w]=++tot;
        x=son[x][w];
      }
      val[x]=t;
    }
    inline int ask(int p){
      int o=K,x=0;
      for(;~o;o--){
        int w=p>>o&1;
        if(son[x][w])x=son[x][w];else x=son[x][w^1];
      }
      return val[x];
    }
    inline void clr(){
      for(int i=0;i<=tot;i++)son[i][0]=son[i][1]=val[i]=0;
      tot=0;
    }
    void solve(int o,int l,int r){
      if(l>r)return;
      if(o<0){
        for(int i=l+1;i<=r;i++)add(q[i],q[l]);
        return;
      }
      int L=l-1,R=r+1;
      for(int i=l;i<=r;i++)if(a[q[i]]>>o&1)_q[++L]=q[i];else _q[--R]=q[i];
      for(int i=l;i<=r;i++)q[i]=_q[i];
      solve(o-1,l,L),solve(o-1,R,r);
      if(l>L||R>r)return;
      for(int i=l;i<=L;i++)ins(a[q[i]],q[i]);
      int ret=~0U>>1,x=0,y=0;
      for(int i=R;i<=r;i++){
        int j=ask(a[q[i]]),tmp=a[q[i]]^a[j];
        if(tmp<ret)ret=tmp,x=q[i],y=j;
      }
      clr();
      add(x,y);
    }
    void dfs(int x,int y,int z){
      col[x]=z;
      if(z==0)p0[++c0]=x;else p1[++c1]=x;
      for(int i=g[x];i;i=nxt[i])if(v[i]!=y)dfs(v[i],x,z^1);
    }
    inline void cal(int n,int*q){
      for(int i=1;i<=n;i++){
        if(i>1)ans=min(ans,a[q[i]]^a[ask(a[q[i]])]);
        ins(a[q[i]],q[i]);
      }
      clr();
    }
    int main(){
      scanf("%d",&Case);
      while(Case--){
        scanf("%d",&n);//n>=3
        for(ed=c0=c1=i=0;i<=n;i++)g[i]=0;
        for(i=1;i<=n;i++)scanf("%d",&a[i]),q[i]=i;//[1,1e9]
        solve(K,1,n);
        dfs(1,0,0);
        ans=~0U>>1;
        cal(c0,p0);
        cal(c1,p1);
        printf("%d\n",ans);
        for(i=1;i<=n;i++)putchar(col[i]+'1');
        puts("");
      }
    }
    

      

    D. Artifacts

    #include<cstdio>
    #include<cstring>
    int i,j,n;
    char s[111111];
    double atk=0,atkrate=0,critdmg=50,critrate=5,e;
    int main(){
      for(i=0;i<25;i++){
        fgets(s+1,10000,stdin);
        n=strlen(s+1);
        double tmp=0,base=0.1;
        bool flag=0;
        for(j=1;j<=n;j++){
          if(s[j]>='0'&&s[j]<='9'){
            if(flag==0)tmp=tmp*10+s[j]-'0';
            else{
              tmp+=base*(s[j]-'0');
              base*=0.1;
            }
          }else if(s[j]=='.'){
            flag=1;
          }
        }
        if(s[1]=='A'&&s[2]=='T'&&s[3]=='K'){
          if(s[4]==' '){
            atkrate+=tmp;
          }else{
            atk+=tmp;
          }
        }
        if(s[1]=='C'&&s[2]=='r'&&s[3]=='i'&&s[4]=='t'){
          if(s[6]=='R'){
            critrate+=tmp;
          }else{
            critdmg+=tmp;
          }
        }
      }
      atk=1500*(1+atkrate*0.01)+atk;
      critrate*=0.01;
      critdmg*=0.01;
      if(critrate>1)critrate=1;
      e=atk*(1-critrate)+atk*(1+critdmg)*critrate;
      printf("%.15f",e);
    }
    

      

    E. Mountain

    #include<cstdio>
    #include<algorithm>
    using namespace std;
    typedef long double ld;
    const int N=105;
    int n,m,all,W,H,o,i,j,S,T,h[N],q[N];
    ld f[2][(1<<((5*2)-1))+1][N],tmp;
    inline void up(ld&a,ld b){a<b?(a=b):0;}
    inline ld solve(int A,int B,int K){
      if(K<=0)return 0;
      if(K<=A)return K;
      if(K>=B)return (A+B)*0.5;
      return (A+B)*0.5-(0.5*(B-K)*(B-K))/(B-A);
    }
    inline ld cal(int x,int S){
      int l,r,L,R,cnt,i,j,k,A,B;
      l=max(x-W,0);
      r=min(x+W,n+1);
      ld ret=0;
      for(i=l;i<r;i++){
        L=max(i-W+1,max(1,x-m));
        R=min(i+W,x);
        A=h[i],B=h[i+1];
        if(A>B)swap(A,B);
        cnt=0;
        for(j=L;j<=R;j++)if(S>>(x-j)&1)q[++cnt]=h[j];
        sort(q+1,q+cnt+1);
        for(j=1;j<=cnt;j=k+1){
          k=j;
          while(k<cnt&&q[k+1]-q[k]<=H*2)k++;
          ret+=solve(A,B,q[k]+H)-solve(A,B,q[j]-H);
        }
      }
      return ret;
    }
    int main(){
      scanf("%d%d%d",&n,&W,&H);
      for(i=1;i<=n;i++)scanf("%d",&h[i]);
      m=W*2-1;
      all=(1<<m)-1;
      for(i=1;i<=n;i++,o^=1){
        for(S=0;S<=all;S++)for(j=0;j<=n;j++)f[o^1][S][j]=0;
        for(S=0;S<=all;S++){
          T=(S<<1)&all;
          tmp=cal(i,S<<1|1)-cal(i,S<<1);
          for(j=0;j<=n;j++){
            up(f[o^1][T][j],f[o][S][j]);
            up(f[o^1][T+1][j+1],f[o][S][j]+tmp);
          }
        }
      }
      for(i=1;i<=n;i++){
        tmp=0;
        for(S=0;S<=all;S++)up(tmp,f[o][S][i]);
        printf("%.15f\n",(double)tmp);
      }
    }
    

      

    F. Fixing Networks

    #include<cstdio>
    #include<cstdlib>
    #include<vector>
    #include<algorithm>
    using namespace std;
    const int N=200005;
    int n,m,D,C,i,j,k;vector<int>g[N];
    void NIE(){
      puts("No");
      exit(0);
    }
    inline int fix(int x){
      while(x<1)x+=m;
      while(x>m)x-=m;
      return x;
    }
    int main(){
      scanf("%d%d%d",&n,&D,&C);
      if(n%2&&D%2)NIE();
      if(1LL*C*(D+1)>n)NIE();
      if(D==0&&n!=C)NIE();
      m=n-(C-1)*(D+1);
      //D+1<=n-(C-1)*(D+1)
      if(D==1){
        if(m!=2)NIE();
        g[1].push_back(2);
        g[2].push_back(1);
      }else{
        for(i=1;i<=m;i++){
          for(j=1;j<=D/2;j++)g[i].push_back(fix(i-j)),g[i].push_back(fix(i+j));
          if(D%2)g[i].push_back(fix(i+m/2));
        }
      }
      for(i=1;i<C;i++){
        for(j=1;j<=D+1;j++)for(k=1;k<=D+1;k++)if(j!=k)g[m+j].push_back(m+k);
        m+=D+1;
      }
      puts("Yes");
      for(i=1;i<=n;i++){
        sort(g[i].begin(),g[i].end());
        for(j=0;j<D;j++)printf("%d%c",g[i][j],j<D-1?' ':'\n');
      }
    }
    

      

    G. Game on Sequence

    #include<cstdio>
    #include<algorithm>
    using namespace std;
    const int N=400005,M=256;
    int n,m,i,op,x,a[N],v[M+1],q[M+1],f[M+1];
    inline bool cmp(int x,int y){return v[x]>v[y];}
    inline bool gao(int x){
      if(x!=v[a[x]])return 1;
      int i,j;
      for(i=0;i<M;i++)q[i]=i;
      sort(q,q+M,cmp);
      for(i=0;i<M;i++)f[i]=0;
      for(i=0;i<M;i++){
        for(j=0;j<8;j++)if(f[q[i]^(1<<j)])break;
        if(q[i]==a[x])return j<8;
        if(j==8)f[q[i]]=1;
      }
    }
    int main(){
      scanf("%d%d",&n,&m);
      for(i=1;i<=n;i++)scanf("%d",&a[i]),v[a[i]]=i;
      while(m--){
        scanf("%d%d",&op,&x);
        if(op==1)a[v[x]=++n]=x;
        else puts(gao(x)?"Grammy":"Alice");
      }
    }
    

      

    H. Fly Me To The Moon

    #include <bits/stdc++.h>
    #define rep(i, a, b) for (int i = a; i <= b; i++)
    #define per(i, a, b) for (int i = a; i >= b; i--)
    using namespace std;
    typedef long long ll;
    
    const int md = 998244353;
    
    inline int add(int x, int y) {
        x += y;
        if (x >= md) x -= md;
        return x;
    }
    
    inline void addx(int &x, int y) {
        x += y;
        if (x >= md) x -= md;
    }
    
    inline int sub(int x, int y) {
        x -= y;
        if (x < 0) x += md;
        return x;
    }
    
    inline void subx(int &x, int y) {
        x -= y;
        if (x < 0) x += md;
    }
    
    inline int mul(int x, int y) { return 1ull * x * y % md; }
    
    inline int fpow(int x, int y) {
        int ans = 1;
        while (y) {
            if (y & 1) ans = mul(ans, x);
            y >>= 1; x = mul(x, x);
        }
        return ans;
    }
    
    vector <int> roots, rev;
    
    void getRevRoot(int base) {
        int n = 1 << base;
        if ((int)roots.size() == n) return;
        roots.resize(n); rev.resize(n);
        for (int i = 1; i < n; i++) rev[i] = (rev[i >> 1] >> 1) | ((i & 1) << (base - 1));
        for (int mid = 1; mid < n; mid <<= 1) {
            int wn = fpow(3, (md - 1) / (mid << 1));
            roots[mid] = 1;
            for (int i = 1; i < mid; i++) roots[i + mid] = mul(roots[i + mid - 1], wn);
        }
    }
    
    void ntt(vector <int> &a, int base) {
        int n = 1 << base;
        for (int i = 0; i < n; i++) {
            if (i < rev[i]) {
                swap(a[i], a[rev[i]]);
            }
        }
        for (int mid = 1; mid < 4 && mid < n; mid <<= 1) {
            for (int i = 0; i < n; i += (mid << 1)) {
                for (int j = 0; j < mid; j++) {
                    int x = a[i + j], y = mul(a[i + j + mid], roots[mid + j]);
                    a[i + j] = add(x, y); a[i + j + mid] = sub(x, y);
                }
            }
        }
        for (int mid = 4; mid < n; mid <<= 1) {
            for (int i = 0; i < n; i += (mid << 1)) {
                for (int j = 0; j < mid; j += 4) {
                    int tmp = mul(a[i + j + mid], roots[mid + j]);
                    a[i + j + mid] = sub(a[i + j], tmp);
                    a[i + j] = add(a[i + j], tmp);
                    tmp = mul(a[i + j + mid + 1], roots[mid + j + 1]);
                    a[i + j + mid + 1] = sub(a[i + j + 1], tmp);
                    a[i + j + 1] = add(a[i + j + 1], tmp);
                    tmp = mul(a[i + j + mid + 2], roots[mid + j + 2]);
                    a[i + j + mid + 2] = sub(a[i + j + 2], tmp);
                    a[i + j + 2] = add(a[i + j + 2], tmp);
                    tmp = mul(a[i + j + mid + 3], roots[mid + j + 3]);
                    a[i + j + mid + 3] = sub(a[i + j + 3], tmp);
                    a[i + j + 3] = add(a[i + j + 3], tmp);
                }
            }
        }
    }
    
    const ll P = 1ll * md * md;
    const int N = 1001 * 1001 + 5, M = 3, U = 1005;
    
    vector <int> F[M], G[M], tmp, ANS;
    int n[M], facn[M], nt[N], ways[U][U], suf[N * 2];
    int lim, k, dis;
    
    int da[M];
    void dfs1(int u) {
        if (u == k + 1) {
            int id = 0;
            for (int i = 1; i <= k; i++) id += da[i] * facn[i - 1];
            if (da[1] == 0 && da[2] == 0) tmp[id] = 1;
            else tmp[id] = md - suf[da[1]*da[1]+da[2]*da[2]];
            return;
        }
        for (int i = 0; i < n[u]; i++) {
            da[u] = i;
            dfs1(u + 1);
        }
    }
    
    void dfs2(int u) {
        if (u == k + 1) {
            int id = 0;
            for (int i = 1; i <= k; i++) id += da[i] * facn[i - 1];
            ways[da[1]][da[2]] = ANS[id];
            return;
        }
        for (int i = 0; i < n[u]; i++) {
            da[u] = i;
            dfs2(u + 1);
        }
    }
    
    vector <int> mul(vector <int> a, vector <int> b, int need, int ntted = 0, int limit = 0) {
        int len = (int)a.size() + (int)b.size() - 1, base = 0;
        if (limit) len = limit;
        while ((1 << base) < len) ++base;
        // cerr << "base = " << base << endl;
        getRevRoot(base);
        for (int i = 0; i < k; i++) {
            F[i].clear(); F[i].resize(1 << base);
            if (!ntted) {
                G[i].clear(); G[i].resize(1 << base);
            }
        }
        for (int i = 0; i < (int)a.size(); i++) F[nt[i]][i] = a[i];
        if (!ntted) {
            for (int i = 0; i < (int)b.size(); i++) G[nt[i]][i] = b[i];
        }
        for (int i = 0; i < k; i++) {
            ntt(F[i], base);
            if (!ntted) ntt(G[i], base);
        }
        for (int i = 0; i < (1 << base); i++) {
            static ll res[M];
            memset(res, 0, sizeof(res));
            for (int j = 0; j < k; j++) {
                for (int t = 0; t < k; t++) {
                    // addx(res[(j + t) % k], mul(F[j][i], G[t][i]));
                    int go = (j + t >= k ? j + t - k : j + t); 
                    res[go] += 1ll * F[j][i] * G[t][i];
                    if (res[go] >= P) res[go] -= P;
                }
            }
            for (int j = 0; j < k; j++) F[j][i] = res[j] % md;
        }
        int inv = fpow(1 << base, md - 2);
        for (int i = 0; i < k; i++) {
            ntt(F[i], base);
            reverse(F[i].begin() + 1, F[i].end());
        }
        vector <int> ans(need);
        for (int i = 0; i < need; i++) ans[i] = mul(inv, F[nt[i]][i]);
        return ans;
    }
    
    vector <int> pinv(vector <int> a, int n) {
        a.resize(n);
        if (n == 1) {
            vector <int> ans(1, fpow(a[0], md - 2));
            return ans;
        }
        vector <int> f0 = pinv(a, (n + 1) >> 1);
        vector <int> tmp = mul(a, f0, n, 0, n), ans = f0;
        for (int i = 0; i < (int)f0.size(); i++) tmp[i] = 0;
        tmp = mul(tmp, f0, n, 1, n); ans.resize(n);
        for (int i = (int)f0.size(); i < n; i++) ans[i] = sub(0, tmp[i]);
        return ans;
    }
    namespace DP{
    int i,j,f[U];
    pair<int,int>e[U];
    void gao(int n){
      e[0].first=e[0].second=1000;
      for(i=1;i<=n;i++)cin>>e[i].first>>e[i].second;
      sort(e,e+n+1);
      for(i=0;i<=n;i++){
        f[i]=ways[e[i].first][e[i].second];
        for(j=0;j<i;j++)if(e[j].second<=e[i].second)f[i]=(f[i]-1LL*f[j]*ways[e[i].first-e[j].first][e[i].second-e[j].second])%md;
      }
      cout<<(f[n]%md+md)%md;
    }
    }
    int main() {
        k = 2;
        for (int i = 1; i <= k; i++) n[i] = 1001;
        int _,__;
        cin >> _ >> __;
        while(_--){
          int x;
          cin>>x;
          suf[x*x]++;
        }
        for(int i=N*2-1;i;i--)suf[i-1]+=suf[i];
        facn[0] = 1;
        for (int i = 1; i <= k; i++) facn[i] = facn[i - 1] * n[i];
        lim = facn[k];
        tmp.resize(lim);
        dfs1(1);
        for (int i = 0; i < lim; i++) {
            int res = 0;
            for (int j = 1; j < k; j++) res += i / facn[j];
            nt[i] = res % k;
        }
        ANS = pinv(tmp, lim);
        dfs2(1);
        DP::gao(__);
    }
    

      

    I. Nim Cheater

    #include<cstdio>
    const int N=20005,M=16384,inf=~0U>>1;
    int n,m,cur,i,x,y,loc[N<<1],val[N],cost[N],fa[N],g[N],nxt[N],size[N],son[N];
    int dp[17][M+1],ans[N],sum[N];
    inline void up(int&a,int b){a<b?(a=b):0;}
    void dfs(int x){
      size[x]=1;
      for(int i=g[x];i;i=nxt[i]){
        dfs(i);
        size[x]+=size[i];
        if(size[i]>size[son[x]])son[x]=i;
      }
    }
    void dfs2(int x,int o){
      int i,j,A=val[x],B=cost[x];
      if(x>1)for(j=0;j<M;j++)if(j<=(j^A)){
        int tmp=dp[o][j];
        up(dp[o][j],dp[o][j^A]+B);
        up(dp[o][j^A],tmp+B);
      }
      ans[x]=sum[x]-dp[o][0];
      for(i=g[x];i;i=nxt[i])if(i!=son[x]){
        for(j=0;j<M;j++)dp[o+1][j]=dp[o][j];
        dfs2(i,o+1);
      }
      if(son[x])dfs2(son[x],o);
    }
    int main(){
      scanf("%d",&m);
      cur=n=1;
      for(i=1;i<=m;i++){
        char op[9];
        scanf("%s",op);
        if(op[0]=='A'){
          scanf("%d%d",&x,&y);
          n++;
          val[n]=x;
          cost[n]=y;
          fa[n]=cur;
          sum[n]=sum[cur]+y;
          nxt[n]=g[cur];
          g[cur]=n;
          cur=n;
        }else cur=fa[cur];
        loc[i]=cur;
      }
      dfs(1);
      for(i=1;i<M;i++)dp[0][i]=-inf;
      dfs2(1,0);
      for(i=1;i<=m;i++)printf("%d\n",ans[loc[i]]);
    }
    

      

    J. Jewel Grab

    #include<cstdio>
    #include<algorithm>
    #include<set>
    using namespace std;
    typedef long long ll;
    const int N=200005,M=524305;
    int n,m,i,op,x,y,col[N],val[N],last[N],pre[N],vis[N],w[N],POS;
    set<int>T[N];
    int v[M],X,Y;ll s[M],ans;
    inline void up(int x){
      v[x]=max(v[x<<1],v[x<<1|1]);
      s[x]=s[x<<1]+s[x<<1|1];
    }
    void build(int x,int a,int b){
      if(a==b){
        v[x]=pre[a];
        s[x]=val[a];
        return;
      }
      int mid=(a+b)>>1;
      build(x<<1,a,mid),build(x<<1|1,mid+1,b);
      up(x);
    }
    void change(int x,int a,int b,int c){
      if(a==b){
        v[x]=pre[a];
        s[x]=val[a];
        return;
      }
      int mid=(a+b)>>1;
      if(c<=mid)change(x<<1,a,mid,c);else change(x<<1|1,mid+1,b,c);
      up(x);
    }
    void go(int x,int a,int b,int c){
      //printf(">> [%d,%d] v=%d X=%d\n",a,b,v[x],X);
      if(c<=a&&v[x]<X){
        Y=b;
        ans+=s[x];
        return;
      }
      if(a==b)return;
      int mid=(a+b)>>1;
      if(c<=mid)go(x<<1,a,mid,c);
      if(Y>=mid)go(x<<1|1,mid+1,b,c);
    }
    inline ll query(int x,int k){
      int o=x;
      ans=0;
      POS++;
      X=x;
      while(k>=0&&o<=n){
        Y=o-1;
        go(1,1,n,o);//find max that pre<x, if no sol then Y=o-1
        //printf("o=%d Y=%d ans=%lld\n",o,Y,ans);
        if(Y==n||!k)break;
        k--;
        o=Y+1;
        int C=col[o];
        if(vis[C]==POS){
          if(w[C]<val[o]){
            ans+=val[o]-w[C];
            w[C]=val[o];
          }
        }else{
          vis[C]=POS;
          w[C]=max(val[pre[o]],val[o]);
          ans+=w[C]-val[pre[o]];
        }
        o++;
      }
      return ans;
    }
    int main(){
      scanf("%d%d",&n,&m);
      for(i=1;i<=n;i++)T[i].insert(0),T[i].insert(n+1);
      for(i=1;i<=n;i++){
        scanf("%d%d",&col[i],&val[i]);
        T[col[i]].insert(i);
        pre[i]=last[col[i]];
        last[col[i]]=i;
      }
      build(1,1,n);
      while(m--){
        scanf("%d%d%d",&op,&x,&y);
        if(op==1){
          scanf("%d",&val[x]);
          set<int>::iterator it=T[col[x]].find(x),j,k;
          j=k=it;
          j--,k++;
          if(*k<=n){
            pre[*k]=*j;
            change(1,1,n,*k);
          }
          T[col[x]].erase(x);
          T[col[x]=y].insert(x);
          j=k=it=T[y].find(x);
          j--,k++;
          pre[x]=*j;
          change(1,1,n,x);
          if(*k<=n){
            pre[*k]=x;
            change(1,1,n,*k);
          }
        }else printf("%lld\n",query(x,y));
      }
    }
    

      

    K. Candy Ads

    #include<cstdio>
    #include<algorithm>
    #include<vector>
    using namespace std;
    typedef unsigned long long ull;
    const int N=50005,M=787,L=2005;
    int n,m,cnt,all,W,H,i,j,x,y,q[N<<1],t,f[N<<1];
    ull fl[L][M],fr[L][M],f1[L][M],f2[L][M],vis0[M],vis1[M];
    vector<int>g[N<<1],h[N<<1];
    struct E{int l,r,x,y,t,v;}e[N];
    inline bool cmpv(const E&a,const E&b){return a.v<b.v;}
    inline bool cmpt(const E&a,const E&b){return a.t<b.t;}
    inline void pre(int lim,ull f[][M]){
      sort(e,e+n,cmpv);
      for(int i=1,j=0,k=0;i<L;i++){
        for(int x=0;x<=all;x++)f[i][x]=f[i-1][x];
        while(j<n&&e[j].v<=i-lim){
          f[i][e[j].t>>6]^=1ULL<<(e[j].t&63);
          j++;
        }
        while(k<n&&e[k].v<=i+lim-1){
          f[i][e[k].t>>6]^=1ULL<<(e[k].t&63);
          k++;
        }
      }
    }
    inline void addedge(int x,int y){
      g[x].push_back(y);
      h[y].push_back(x);
    }
    inline bool visit(int x){
      if(x<n)return vis0[x>>6]>>(x&63)&1;
      x-=n;
      return vis1[x>>6]>>(x&63)&1;
    }
    inline void flip(int x){
      if(x<n){
        vis0[x>>6]^=1ULL<<(x&63);
        return;
      }
      x-=n;
      vis1[x>>6]^=1ULL<<(x&63);
    }
    void dfs0(int x){
      if(!visit(x))return;
      flip(x);
      for(int i=0;i<g[x].size();i++)dfs0(g[x][i]);
      if(x<n){
        int L=e[x].l,R=e[x].r,B=e[x].x,C=e[x].y;
        for(int i=0;i<=all;i++){
          ull S=fl[R][i]&fr[L][i]&f1[B][i]&f2[C][i];
          if(i==(x>>6))S^=1ULL<<(x&63);
          while(1){
            S&=vis1[i];
            if(!S)break;
            dfs0((i<<6|__builtin_ctzll(S))+n);
          }
        }
      }
      q[++t]=x;
    }
    void dfs1(int x){
      if(!visit(x))return;
      flip(x);
      f[x]=cnt;
      for(int i=0;i<h[x].size();i++)dfs1(h[x][i]);
      if(x<n)return;
      x-=n;
      int L=e[x].l,R=e[x].r,B=e[x].x,C=e[x].y;
      for(int i=0;i<=all;i++){
        ull S=fl[R][i]&fr[L][i]&f1[B][i]&f2[C][i];
        if(i==(x>>6))S^=1ULL<<(x&63);
        while(1){
          S&=vis0[i];
          if(!S)break;
          dfs1(i<<6|__builtin_ctzll(S));
        }
      }
    }
    int main(){
      scanf("%d%d%d",&n,&W,&H);
      all=(n-1)>>6;
      for(i=0;i<n;i++)scanf("%d%d%d%d",&e[i].l,&e[i].r,&e[i].x,&e[i].y),e[i].t=i;
      for(i=0;i<n;i++){
        fl[e[i].l][i>>6]^=1ULL<<(i&63);
        fr[e[i].r][i>>6]^=1ULL<<(i&63);
      }
      for(i=1;i<L;i++)for(j=0;j<=all;j++)fl[i][j]|=fl[i-1][j];
      for(i=L-1;i;i--)for(j=0;j<=all;j++)fr[i-1][j]|=fr[i][j];
      for(i=0;i<n;i++)e[i].v=e[i].x;
      pre(W,f1);
      for(i=0;i<n;i++)e[i].v=e[i].y;
      pre(H,f2);
      sort(e,e+n,cmpt);
      scanf("%d",&m);
      while(m--){
        scanf("%d%d",&x,&y);
        x--,y--;
        addedge(x+n,y);
        addedge(y+n,x);
      }
      for(i=0;i<=all;i++)vis0[i]=vis1[i]=0;
      for(i=0;i<n;i++)vis0[i>>6]^=1ULL<<(i&63);
      for(i=0;i<=all;i++)vis1[i]=vis0[i];
      for(i=0;i<n+n;i++)dfs0(i);
      for(i=0;i<=all;i++)vis0[i]=vis1[i]=0;
      for(i=0;i<n;i++)vis0[i>>6]^=1ULL<<(i&63);
      for(i=0;i<=all;i++)vis1[i]=vis0[i];
      for(i=t;i;i--)cnt++,dfs1(q[i]);
      for(i=0;i<n;i++)if(f[i]==f[i+n])return puts("No"),0;
      puts("Yes");
      for(i=0;i<n;i++)putchar(f[i]<f[i+n]?'0':'1');
      puts("");
    }
    

      

    L. Random Permutation

    //n!*n!/n^n
    #include<cstdio>
    int n,i;double ans;
    int main(){
      scanf("%d",&n);
      ans=1;
      for(i=1;i<=n;i++)ans*=i*i,ans/=n;
      printf("%.15f",ans);
    }
    

      

  • 相关阅读:
    【vue知识点】2)vue登录认证
    【vue知识点】1)vue生命周期
    【VSC】.txt文件打开乱码
    【VSC】git+github/码云+VSCode
    【vsCode】我安装了哪些扩展插件
    【VCS】种草VSCode
    【vue】父子组件间通信----传函数
    最大子列和
    jedisLock—redis分布式锁实现
    基础的重要性(程序员之路)
  • 原文地址:https://www.cnblogs.com/clrs97/p/15805591.html
Copyright © 2020-2023  润新知