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);
}

  

posted @ 2022-01-14 21:51  Claris  阅读(154)  评论(0编辑  收藏  举报