• 多校联测20191009test


    本人水平有限,题解不到为处,请多多谅解

    本蒟蒻谢谢大家观看

    题目:

    1 文体两开花
    1.1题目描述
    众所周知,小G擅长文体两开花。 现在小G手中拿到了一棵树,这棵树的每个节点上都有一个非负整数权值vali。 为了展现自己深不可测的开花功底,小G会对这棵树进行一系列操作,具体表现为修改某个节点x
    的权值。在每次修改之后,小G想要你告诉他,所有与节点x距离不超过2的所有节点的权值异或和是
    多少。
    1.2输入格式
    从文件blossom.in中读入数据。 输入数据第一行包含两个正整数n,q,表示树的节点数以及修改/询问次数。
    第一行n个空格隔开的正整数vali,表示每个点的权值。
    接下来n~1行,每行两个正整数x,y,表示一条树边(x,y)
    接下来q行,每行两个整数x,v,表示将节点x的权值修改成v
    1.3输出格式
    输出到文件blossom.out中。
    为避免输出过量,记第i次询问的答案为ansi,你只需要输出∑(q)i=1ansi×i2109+7取模的结果即可。
    1.4样例1输入
    5 3
    1 2 3 4 5
    1 2
    1 3
    2 4
    2 5
    3 6
    4 7
    5 8
    1.5样例1输出
    117
    1.6样例1解释
    3次询问对应的答案分别为5,1,12
    对于30%的数据,1n,q1000
    对于60%的数据,1n,q105
    对于100%的数据,1n,q106,1x,yn,0vali,v<230
     
    sol
    模拟即可:
    注意直接预处理出距离为2以内的异或值,改变的时候全部改一下即可
    时间复杂度O(n+q)
    code:
     
     1 #include <bits/stdc++.h>
     2 #pragma GCC optmize(3)
     3 #define int long long
     4 using namespace std;
     5 int ans;
     6 int n,q;
     7 inline int read(){
     8     int x=0,f=1;char ch=getchar();
     9     while(!isdigit(ch)){if(ch=='-')f=-1;ch=getchar();}
    10     while(isdigit(ch)){x=(x<<1)+(x<<3)+(ch^48);ch=getchar();}
    11     return x*f;
    12 }
    13 const int N=1001000,mod=1e9+7;
    14 int to[N*2],head[N],Next[N*2],dep1[N],dep2[N],a[N],fa[N];
    15 int cnt=0;
    16 void add(int x,int y){to[++cnt]=y;Next[cnt]=head[x];head[x]=cnt;}
    17 void dfs(int x,int ffa)
    18 {
    19     dep1[fa[x]]^=a[x];//预处理出与 x 同一距离根节点为1的异或值 
    20     dep2[fa[ffa]]^=a[x];//预处理出与 ffa 同一距离根节点为1的异或值 
    21     for (int i=head[x];i;i=Next[i])
    22     {
    23         int u=to[i];
    24         if (u==ffa) continue;
    25         fa[u]=x;//u 的父亲为 x 
    26         dfs(u,x);
    27     }
    28     //cout<<"dep1[fa[x]]= "<<dep1[fa[x]]<<" dep2[fa[ffa]]= "<<dep2[fa[ffa]]<<" fa[x]= "<<fa[x]<<" x= "<<x<<" fa[ffa]= "<<fa[ffa]<<" ffa= "<<ffa<<" a[x]= "<<a[x]<<endl;
    29 }
    30 signed main()
    31 {
    32     //freopen("blossom.in" ,"r",stdin );
    33     //freopen("blossom.out","w",stdout);
    34     
    35     n=read();q=read();
    36     for (int i=1;i<=n;i++) a[i]=read();
    37     for (int i=1;i< n;i++)
    38     {
    39         int x,y;
    40         x=read();
    41         y=read();
    42         add(x,y);add(y,x);
    43     }
    44     dfs(1,0);
    45     for (int i=1;i<=q;i++)
    46     {
    47         int x,v;
    48         x=read();v=read();
    49         //cout<<"dep1[fa[x]]= "<<dep1[fa[x]]<<" dep2[fa[fa[x]]]= "<<dep2[fa[fa[x]]]<<" fa[x]= "<<fa[x]<<" fa[fa[x]]= "<<fa[fa[x]]<<" a[x]= "<<a[x]<<" v= "<<v<<endl;
    50         dep1[fa[x]]^=a[x]^v;//异或值改变 
    51         dep2[fa[fa[x]]]^=a[x]^v;//同理 
    52         a[x]=v;//更新a[x] 
    53         
    54         int anslin=dep1[x]^dep2[x];
    55         if (fa[fa[x]]) anslin^=a[fa[fa[x]]];//若有祖辈 则继续异或 ,因为祖辈不能改变之前的值 
    56         if (fa[x]) anslin^=a[fa[x]]^dep1[fa[x]];//若有父辈 则要加入父辈值 父辈可改变之前的值 
    57         else anslin^=a[x];//如果没有父辈,则肯定也没有祖辈 直接异或本身 
    58         ans+=1ll*anslin*i%mod*i;//边乘边模,减少复杂度 
    59         ans%=mod;        
    60 //        cout<<anslin<<endl;
    61     }
    62     printf("%lld
    ",ans);
    63     return 0;
    64 }
    65 /*
    66 5 3
    67 1 2 3 4 5
    68 1 2
    69 1 3
    70 2 4
    71 2 5
    72 3 6
    73 4 7
    74 5 8
    75 
    76 */

    但以上代码只有60分,会T掉4个点,如果你把快读改成一个更优的话,AC100

     如下快读

     1 inline char read() {
     2     static const int IN_LEN = 1000000;
     3     static char buf[IN_LEN], *s, *t;
     4     return (s == t ? t = (s = buf) + fread(buf, 1, IN_LEN, stdin), (s == t ? -1 : *s++) : *s++);
     5 }
     6 template<class T>
     7 inline void read(T &x) {
     8     static bool iosig;
     9     static char c;
    10     for (iosig = false, c = read(); !isdigit(c); c = read()) {
    11         if (c == '-') iosig = true;
    12         if (c == -1) return;
    13     }
    14     for (x = 0; isdigit(c); c = read()) x = x * 10 + (c ^ '0');
    15     if (iosig) x = -x;
    16 }

    考场上我是直接暴力枚举,使用了换根法,导致每次都跑了一遍dfs,一共q次,再加上O(n*q)的暴力枚举

    导致我只拿了30分,其余全部TLE了,考场SB代码:

    code:

      1 #include<bits/stdc++.h>
      2 #pragma GCC optimize(3)
      3 #define int long long
      4 const int mod=1e9+7;
      5 const int N=1e6+10; 
      6 using namespace std;
      7 int yzl;
      8 int n,q,w,cnt,fuck,vv;
      9 int a[N]; 
     10 int tot,ver[N],head[N],nxt[N];
     11 int dep[N],depp[N],ans[N];
     12 void inint(){
     13     freopen("blossom.in","r",stdin);
     14     freopen("blossom.out","w",stdout);
     15 }
     16 inline int read(){
     17     int x=0,f=1;char ch=getchar();
     18     while(!isdigit(ch)){if(ch=='-')f=-1;ch=getchar();}
     19     while(isdigit(ch)){x=(x<<1)+(x<<3)+(ch^48);ch=getchar();}
     20     return x*f;
     21 }
     22 void add(int x,int y){
     23     ++tot;
     24     ver[tot]=y;
     25     nxt[tot]=head[x];
     26     head[x]=tot;
     27 }
     28 void dfs(int x,int fa){
     29 //    dep[x]=0;
     30     depp[x]=depp[fa]+1;
     31     for(int i=head[x];i;i=nxt[i]){
     32         int y=ver[i];
     33         if(y!=fa){
     34         //    dep[y]=dep[x]+1;
     35             dfs(y,x);
     36             depp[y]=depp[x]+1;
     37             //cout<<"dep= "<<dep[y]<<endl;
     38         }
     39     }
     40 }
     41 void dfs2(int x,int fa){
     42     dep[x]=dep[fa]+1;
     43     for(int i=head[x];i;i=nxt[i]){
     44         int y=ver[i];
     45         if(y!=fa){
     46             
     47             dfs2(y,x);
     48             w=x;
     49             dep[y]=dep[x]+1;
     50         //    cout<<"x= "<<x<<" y= "<<y<<endl;
     51         }
     52     }
     53 }
     54 int lowbit(int x){
     55     return x&-x;
     56 }
     57 void change(int x,int v){
     58     while(x<=n){
     59         a[x]=v;
     60         x+=lowbit(x);
     61     }
     62 }
     63 signed main()
     64 {
     65     inint();
     66     n=read(),q=read();
     67     for(int i=1;i<=n;i++){
     68         a[i]=read();
     69     }
     70     for(int i=1;i<n;i++){
     71         int x,y;
     72         x=read(),y=read();
     73         add(x,y);
     74         add(y,x);
     75     }
     76     dfs2(1,0);
     77     cnt=0;
     78     while(q--){
     79         cnt++;
     80         fuck=0,vv=0;
     81         int x,v;
     82         x=read(),v=read();
     83         dfs(x,0);
     84         //change(x,v);
     85         a[x]=v;
     86         vv=a[x];
     87         for(int i=1;i<=n;i++){
     88             if(abs(depp[x]-depp[i])<=2&&abs(depp[x]-depp[i])!=0){
     89                 
     90                 ans[cnt]=vv^a[i];
     91                 vv=vv^a[i];
     92                 //cout<<"a[x]= "<<a[x]<<endl;
     93                 //fuck=v^a[i];
     94                 //cout<<"ans= "<<ans[cnt]<<" cnt= "<<cnt<<endl;
     95                 //cout<<"v= "<<v<<endl;
     96                 //cout<<"i= "<<i<<" a[i]= "<<a[i]<<" vv= "<<vv<<" ans[cnt]= "<<ans[cnt]<<endl; 
     97                 //cout<<"i= "<<i<<endl;
     98             }
     99         //cout<<"depp= "<<depp[i]-1<<" i= "<<i<<endl;
    100     }
    101     
    102         //cout<<dep[x]<<endl;
    103     }
    104     for(int i=1;i<=cnt;i++){
    105         yzl+=ans[i]*i*i;
    106         //cout<<"ans[i]= "<<ans[i]<<endl;
    107         //cout<<"yzl= "<<yzl<<endl;
    108     }
    109     printf("%lld
    ",(yzl%mod));
    110     return 0;
    111 }
    112 /*
    113 5 3 
    114 1 2 3 4 5 
    115 1 2 
    116 1 3 
    117 2 4 
    118 2 5 
    119 3 6 
    120 4 7 
    121 5 8
    122 
    123 117
    124 */

    心得总结:尽管我现在还是弱鸡一枚连多校题只能开暴力(还是只有NOIP难度),得分现在加起来连50都没有,但是原来我可能连暴力都打不满,经过2个月的训练,代码能力也逐渐提升了。

    有些神犇大佬们不屑于做的题目但他们可能会掉意轻心,比如(一些小细节),可能最后得分还不如最浅显的暴力。

    最后还是那句话:只要坚持不懈,就一点会成功无论结果如何,只要自己尽最大的努力,也不会有遗憾了

     
     
     
     
  • 相关阅读:
    图论算法 有图有代码 万字总结 向前辈致敬
    关闭和打开键盘的通知
    (copy)赋值构造函数的4种调用时机or方法
    构造函数的分类
    Uva
    Uva
    The 2018 ACM-ICPC Asia Qingdao Regional Contest F
    The 2018 ACM-ICPC Asia Qingdao Regional Contest E Plants vs. Zombies(ZOJ 4062)
    K Color Graph
    Cow and Fields
  • 原文地址:https://www.cnblogs.com/nlyzl/p/11644589.html
Copyright © 2020-2023  润新知