• CF1479X Codeforces Round #700


    C Continuous City(图的构造)

    题目大意:让你构造一个nle 32的有向无环无重边图,使得从1走到n的所有路径长度在L,R之间,且每种长度的路径只有唯一一条,$L,Rle 1e6$

    构造图的妙妙题目

    先考虑$[1,2^{k}]$的情况

    利用归纳法构图

    假设已经构造完$[1,2^{k}]$的图,现在要构造$[1,2^{k+1}]$的图

    新点的编号为$k+3$,把编号为$2sim k+2$的点,向$k+3$连一条长度为$2^{x-2}$的边,再把$1$和$k+3$连一条长度为$1$的边

    这是把值域扩展的一个过程!$[1,k+2]$的每个点覆盖的值域就是$[1,2^{k}]$

    [1,1]->[2,2] [1,2]->[3,4] [1,4]->[5,8] [1,8]->[9,16] [1,16]->[17,32] 再加上1->1

    如果值域大小不是$2^{k}$,利用上面的值域覆盖的思想,我们可以再添加一个点处理$[1,S]$,最后填一个点处理$[L,R]$

     1 const int N1=35; const ll inf=0x3f3f3f3f3f3f3f3fll;
     2 
     3 int L,R;
     4 int n,m,len;
     5 int mp[N1][N1];
     6 
     7 int main()
     8 {
     9     freopen("a.in","r",stdin);
    10     scanf("%d%d",&L,&R); len=R-L+1;
    11     mp[1][2]=1;
    12     while((1<<(n+1))<=len) n++; n+=2; 
    13     for(int k=0;k<=n-3;k++)
    14     {
    15         mp[1][k+3]=1;
    16         for(int j=2;j<=k+2;j++) mp[j][k+3]=(1<<(j-2));
    17     }
    18     int tmp=len;
    19     if(len!=(1<<(n-2))) 
    20     {
    21         for(int k=n-2;k>=1;k--)
    22         {
    23             if(tmp>(1<<k))
    24             {
    25                 mp[k+2][n+1]=tmp-(1<<k);
    26                 tmp-=(1<<k);
    27             }
    28             if(!tmp) break;
    29         }
    30         if(tmp==1) mp[1][n+1]=1, tmp--;
    31         else if(tmp==2) mp[1][n+1]=1, mp[2][n+1]=1, tmp-=2;
    32         n++;
    33     }
    34     if(L!=1)
    35     {
    36         mp[n][n+1]=L-1;
    37         n++;
    38     }
    39     for(int i=1;i<=n;i++) for(int j=i+1;j<=n;j++) if(mp[i][j]) m++;
    40     printf("YES 
    %d %d
    ",n,m);
    41     for(int i=1;i<=n;i++) for(int j=i+1;j<=n;j++) if(mp[i][j]) 
    42     {
    43         printf("%d %d %d 
    ",i,j,mp[i][j]);
    44     }
    45     return 0;
    46 }
    View Code

    D Odd Mineral Resource (随机化异或+主席树)

    题目大意:给你一棵树,每个点有一个权值,有$Q$个询问,每次输出$x,y$简单路径上任意一个$[L,R]$内且出现次数为奇数次的权值$N,Qle 3e5$

    最容易想到的就是树上莫队了,然而$O(nsqrt n)$会被卡掉 也可能是我常数大

      1 using namespace std;
      2 const int N1=600005; const ll inf=0x3f3f3f3f3f3f3f3fll;
      3 
      4 template<typename _T> void read(_T &ret)
      5 {
      6     ret=0; _T fh=1; char c=getchar();
      7     while(c<'0'||c>'9'){ if(c=='-') fh=-1; c=getchar(); }
      8     while(c>='0'&&c<='9'){ ret=ret*10+c-'0'; c=getchar(); }
      9     ret=ret*fh;
     10 }
     11 template<typename _T> void out(_T ret)
     12 {
     13     if(ret) out(ret/10); else return ;
     14     putchar(ret%10+'0');
     15 }
     16 struct EDGE{
     17 int to[N1],nxt[N1],head[N1],cte;
     18 void ae(int u,int v)
     19 { cte++; to[cte]=v; nxt[cte]=head[u]; head[u]=cte; }
     20 }e;
     21 
     22 int n,nn,Q,sq,S,P;
     23 int a[N1],st[N1],ed[N1],tot,pos[N1],type[N1];
     24 int ids[N1],idp[N1];
     25 
     26 struct QUES{ 
     27 int lp,rp,x,y,f,l,r,id,ans;
     28 }qu[N1];
     29 int cmp0(QUES aa,QUES bb)
     30 {
     31     if(ids[aa.lp]==ids[bb.lp]) return ids[aa.rp]<ids[bb.rp];
     32     else return ids[aa.lp]<ids[bb.lp];
     33 }
     34 int cmp1(QUES aa,QUES bb)
     35 {
     36     return aa.id<bb.id;
     37 }
     38 
     39 int ff[N1][20],dep[N1];
     40 void dfs0(int u,int fa)
     41 {
     42     st[u]=++tot; pos[tot]=u; type[tot]=1;
     43     for(int j=e.head[u];j;j=e.nxt[j])
     44     {
     45         int v=e.to[j]; if(v==fa) continue;
     46         ff[v][0]=u; dep[v]=dep[u]+1; dfs0(v,u);
     47     }
     48     ed[u]=++tot; pos[tot]=u; type[tot]=-1;
     49 }
     50 void getfa()
     51 {
     52     for(int j=1;j<=18;j++)
     53     for(int i=1;i<=n;i++)
     54         ff[i][j]=ff[ff[i][j-1]][j-1];
     55 }
     56 int lca(int x,int y)
     57 {
     58     if(dep[x]<dep[y]) swap(x,y);
     59     for(int j=18;j>=0;j--) if(dep[ff[x][j]]>=dep[y])
     60         x=ff[x][j];
     61     if(x==y) return x;
     62     int ans=0;
     63     for(int j=18;j>=0;j--) 
     64     {
     65         if(ff[x][j]!=ff[y][j]) x=ff[x][j], y=ff[y][j];
     66         else ans=ff[x][j];
     67     }
     68     return ans;
     69 }
     70 
     71 int num[N1],sum[N1],vis[N1];
     72 int L,R;
     73 void upd(int w,int p)
     74 {
     75     num[w]+=p; 
     76     if(num[w]&1) sum[idp[w]]++; else sum[idp[w]]--;
     77 }
     78 void pushx(int y)
     79 {
     80     if(vis[pos[y]]) upd(a[pos[y]],-1), vis[pos[y]]=0;
     81     else upd(a[pos[y]],1), vis[pos[y]]=1;
     82 } 
     83 int solve(int q)
     84 {
     85     int x=qu[q].x, y=qu[q].y, lw=qu[q].l ,rw=qu[q].r, F=qu[q].f;
     86     sta=clock();
     87     if(x!=F&&y!=F) pushx(st[F]);
     88     for(;R<qu[q].rp;R++) pushx(R+1);
     89     for(;qu[q].lp<L;L--) pushx(L-1);
     90     for(;qu[q].rp<R;R--) pushx(R);
     91     for(;L<qu[q].lp;L++) pushx(L);
     92     End=clock(); tt0+=End-sta; 
     93     
     94     sta=clock();
     95     if(idp[lw]==idp[rw]){
     96         for(int i=lw;i<=rw;i++) if(num[i]&1) return i;
     97     }else{
     98         for(int i=lw;i<=idp[lw]*P;i++) if(num[i]&1) return i;
     99         for(int i=(idp[rw]-1)*P+1;i<=rw;i++) if(num[i]&1) return i;
    100         for(int i=idp[lw]+1;i<=idp[rw]-1;i++) if(sum[i]>=1)
    101             for(int j=(i-1)*P+1;j<=i*P;j++) if(num[j]&1) return j;
    102     }
    103     return -1;
    104 }
    105 
    106 int main()
    107 {
    108     freopen("a.txt","r",stdin);
    109     freopen("a0.out","w",stdout);
    110     scanf("%d%d",&n,&Q); 
    111     nn=2*n; P=sqrt(n); S=1000;
    112     for(int i=1;i<=n;i++) read(a[i]);
    113     for(int i=1;i<=n;i++) idp[i]=(i-1)/P+1;
    114     for(int i=1;i<=nn;i++) ids[i]=(i-1)/S+1;
    115     int x,y,F;
    116     for(int i=1;i<n;i++) read(x), read(y), e.ae(x,y), e.ae(y,x);
    117     dep[1]=1; dfs0(1,0); getfa();
    118     for(int q=1;q<=Q;q++) 
    119     {
    120         read(x), read(y), read(qu[q].l), read(qu[q].r); qu[q].id=q;
    121         F=lca(x,y); qu[q].f=F;
    122         if(x==F) qu[q].lp=st[x], qu[q].rp=st[y];
    123         else if(y==F) qu[q].lp=st[y], qu[q].rp=st[x];
    124         else{
    125             if(st[x]>st[y]) swap(x,y);
    126             qu[q].lp=ed[x], qu[q].rp=st[y];
    127         }
    128         qu[q].x=x, qu[q].y=y;
    129     }
    130     sort(qu+1,qu+Q+1,cmp0); 
    131     L=nn+1,R=nn+1;
    132     for(int q=1;q<=Q;q++) 
    133     {
    134         x=qu[q].x, y=qu[q].y; //l=qu[q].l, r=qu[q].r; 
    135         qu[q].ans=solve(q);
    136         if(x!=qu[q].f&&y!=qu[q].f) pushx(st[qu[q].f]);
    137         End=clock(); tt1+=End-sta; 
    138     }
    139     sort(qu+1,qu+Q+1,cmp1);
    140     for(int q=1;q<=Q;q++) 
    141         if(qu[q].ans<0) puts("-1");
    142         else out(qu[q].ans), puts("");
    143     return 0;
    144 }
    View Code

    题解提供了一种成功率很高的随机化异或做法

    考虑把点权等距拉长到$[1,2^{64}]$,维护路径的异或和

    拉长后,异或碰撞,即异或和为$0$但存在出现奇数次的权值的概率非常低,是1/值域,$Q$次询问也不会有多大影响

    主席树维护$f(1,x,l,r)$表示$1$到$x$路径上所有点权在$l,r$范围内的异或和,线段树二分找答案

      1 using namespace std;
      2 const int N1=300005; const int M1=N1*66; const ll inf=0x3f3f3f3f3f3f3f3fll;
      3 
      4 template<typename _T> void read(_T &ret)
      5 {
      6     ret=0; _T fh=1; char c=getchar();
      7     while(c<'0'||c>'9'){ if(c=='-') fh=-1; c=getchar(); }
      8     while(c>='0'&&c<='9'){ ret=ret*10+c-'0'; c=getchar(); }
      9     ret=ret*fh;
     10 }
     11 template<typename _T> void out(_T ret)
     12 {
     13     if(ret) out(ret/10); else return ;
     14     putchar(ret%10+'0');
     15 }
     16 struct EDGE{
     17 int to[N1*2],nxt[N1*2],head[N1],cte;
     18 void ae(int u,int v)
     19 { cte++; to[cte]=v; nxt[cte]=head[u]; head[u]=cte; }
     20 }e;
     21 struct SEG{
     22 int ls[M1],rs[M1],root[N1],tot; ll xsum[M1];
     23 void upd(ll x,ll l,ll r,int r1,int &r2)
     24 {
     25     if(!r2||r1==r2){ r2=++tot; ls[r2]=ls[r1]; rs[r2]=rs[r1]; xsum[r2]=xsum[r1]^x; }
     26     if(l==r) return;
     27     ll mid=(l+r)>>1;
     28     if(x<=mid) upd(x,l,mid,ls[r1],ls[r2]);
     29     else upd(x,mid+1,r,rs[r1],rs[r2]);
     30 }
     31 inline ll calc(int r1,int r2,int r3,int r4)
     32 { return xsum[r1]^xsum[r2]^xsum[r3]^xsum[r4]; }
     33 ll query(ll L,ll R,ll l,ll r,int r1,int r2,int r3,int r4)
     34 {
     35     ll mid=(l+r)>>1;
     36     if(l==r) return calc(r1,r2,r3,r4);
     37     if(L<=l&&r<=R)
     38     {
     39         if(!calc(r1,r2,r3,r4)) return 0;
     40         if(calc(ls[r1],ls[r2],ls[r3],ls[r4])) return query(L,R,l,mid,ls[r1],ls[r2],ls[r3],ls[r4]);
     41         else return query(L,R,mid+1,r,rs[r1],rs[r2],rs[r3],rs[r4]);
     42     }
     43     ll ans=0;
     44     if(L<=mid&&!ans) ans=query(L,R,l,mid,ls[r1],ls[r2],ls[r3],ls[r4]);
     45     if(R>mid&&!ans) ans=query(L,R,mid+1,r,rs[r1],rs[r2],rs[r3],rs[r4]);
     46     return ans;
     47 }
     48 }s;
     49 
     50 int n,Q;
     51 int a[N1];
     52 map<ll,int>real; ll tra[N1];
     53 
     54 int ff[N1][20],dep[N1];
     55 void dfs0(int u,int fa)
     56 {
     57     for(int j=e.head[u];j;j=e.nxt[j])
     58     {
     59         int v=e.to[j]; if(v==fa) continue;
     60         ff[v][0]=u; dep[v]=dep[u]+1; 
     61         s.upd(tra[a[v]],1,inf,s.root[u],s.root[v]);
     62         dfs0(v,u);
     63     }
     64 }
     65 void getfa()
     66 {
     67     for(int j=1;j<=18;j++)
     68     for(int i=1;i<=n;i++)
     69         ff[i][j]=ff[ff[i][j-1]][j-1];
     70 }
     71 int lca(int x,int y)
     72 {
     73     if(dep[x]<dep[y]) swap(x,y);
     74     for(int j=18;j>=0;j--) if(dep[ff[x][j]]>=dep[y])
     75         x=ff[x][j];
     76     if(x==y) return x;
     77     int ans=0;
     78     for(int j=18;j>=0;j--) 
     79     {
     80         if(ff[x][j]!=ff[y][j]) x=ff[x][j], y=ff[y][j];
     81         else ans=ff[x][j];
     82     }
     83     return ans;
     84 }
     85 
     86 int main()
     87 {
     88     sta=clock();
     89     scanf("%d%d",&n,&Q); 
     90     for(int i=1;i<=n;i++) read(a[i]);
     91     for(int i=1;i<=n;i++) tra[i]=inf/n*i, real[inf/n*i]=i;
     92     int x,y,l,r,F; ll ans;
     93     for(int i=1;i<n;i++) read(x), read(y), e.ae(x,y), e.ae(y,x);
     94     dep[1]=1; s.upd(tra[a[1]],1,inf,0,s.root[1]);
     95     dfs0(1,0); getfa();
     96     
     97     for(int q=1;q<=Q;q++) 
     98     {
     99         read(x), read(y), read(l), read(r);
    100         F=lca(x,y);
    101         ans=s.query(tra[l],tra[r],1,inf,s.root[x],s.root[y],s.root[F],s.root[ff[F][0]]);
    102         if(!ans) ans=-1; else ans=real[ans];
    103         printf("%lld
    ",ans);
    104     }
    105     return 0;
    106 }
    View Code
  • 相关阅读:
    Mybatis学习-ResultMap
    MySql模糊查询 concat()函数
    Spring学习-依赖注入
    Struts2学习-struts执行过程简述
    Struts2学习-jsp中超链接传参问题
    Struts2学习-struts.xml文件配置
    第四次作业
    第三次作业
    Django -Ajax
    Django -ORM
  • 原文地址:https://www.cnblogs.com/guapisolo/p/14407686.html
Copyright © 2020-2023  润新知