首页 > 代码库 > [ CodeVS冲杯之路 ] P2492

[ CodeVS冲杯之路 ] P2492

  不充钱,你怎么AC?

  题目:http://codevs.cn/problem/2492/

 

  在此先orz小胖子,教我怎么路径压缩链表,那么这样就可以在任意节点跳进链表啦(手动@LCF)

  对于查询操作,直接树状数组(以下简称BIT)维护,修改操作就一个个暴力开方搞,再用差值单点更新BIT

  不过这样会TLE,要加一点优化对不对,正如开头所说的路径压缩链表

  路径压缩链表其实就是个并查集,在普通的链表里,删去两个连续的节点后会是下面这种情况,如删去2,3

  技术分享

  当访问 2 的时候,会跳到3,但 3 已经删除了,这就不合法了

  于是我们要用路径压缩,搞成下面这种情况

  技术分享

  它是不是非常优秀,就按照并查集一样实现,具体参考代码

  那么我们想,为什么要搞链表呢?修改的时候直接暴力扫不就行了?

  显然 sqrt(1)=1,那么对于 1 的操作不就是无用功?那么记录下来 1 的位置,然后用链表在扫的时候把它跳转掉,因为区间可以是中间的一段,所以要用路径压缩

  记得开long long,然后数组多开 1 个,因为若 r 为极限数据,那么跳到最后一个还会往后面跳一个,没开大的话会RE(反正多开一点好一些),记得链表的 f[n+1]=n+1 也要赋值

 1 #include<cstdio> 2 #include<cstdlib> 3 #include<cstring> 4 #include<cmath> 5 #include<iostream> 6 #include<algorithm> 7 typedef long long LL; 8 using namespace std; 9 10 const int N=100002;11 LL a[N],s[N];12 int f[N],n;13 namespace QuQ14 {15     inline int lowbit(int x)16     {17         return x&-x;18     }19     inline void plus(int x,LL k)20     {21         while (x<=n)22         {23             a[x]+=k;24             x+=lowbit(x);25         }26     }27     inline LL sum(int x)28     {29         LL k=0;30         while (x)31         {32             k+=a[x];33             x-=lowbit(x);34         }35         return k;36     }37 }38 namespace OvO39 {40     inline LL read()41     {42         char ch=getchar();43         LL k=0;44         while (ch<0||ch>9) ch=getchar();45         while (ch>=0&&ch<=9)46         {47             k=k*10+ch-0;48             ch=getchar();49         }50         return k;51     }52     inline void write(LL x)53     {54         if (x>9) write(x/10);55         putchar(x%10+0);56     }57 }58 inline int find(int x)59 {60     return f[x]==x?x:f[x]=find(f[x]);61 }62 int main()63 {64     int m,i,l,r;65     LL x;66     n=OvO::read();67     for (i=1;i<=n;i++)68     {69         s[i]=OvO::read();70         QuQ::plus(i,s[i]);71         f[i]=i;72     }73     f[n+1]=n+1;74     m=OvO::read();75     while (m--)76     {77         x=OvO::read();78         l=OvO::read();79         r=OvO::read();80         if (l>r) swap(l,r);81         if (x)82         {83             OvO::write(QuQ::sum(r)-QuQ::sum(l-1));84             putchar(\n);85         }86         else for (l=find(l);l<=r;l=find(l+1))87         {88             x=s[l];89             x-=s[l]=sqrt(s[l]);90             if (s[l]==1) f[l]=find(l+1);91             QuQ::plus(l,-x);92         }93     }94     return 0;95 }

 

[ CodeVS冲杯之路 ] P2492