「Poetize4」上帝造题的七分钟2

描述 Description
"第一分钟,X说,要有数列,于是便给定了一个正整数数列。
第二分钟,L说,要能修改,于是便有了对一段数中每个数都开平方(下取整)的操作。
第三分钟,k说,要能查询,于是便有了求一段数的和的操作。
第四分钟,彩虹喵说,要是noip难度,于是便有了数据范围。
第五分钟,诗人说,要有韵律,于是便有了时间限制和内存限制。
第六分钟,和雪说,要省点事,于是便有了保证运算过程中及最终结果均不超过64位有符号整数类型的表示范围的限制。
第七分钟,这道题终于造完了,然而,造题的神牛们再也不想写这道题的程序了。"
——《上帝造题的七分钟·第二部》
所以这个神圣的任务就交给你了。
输入格式 InputFormat
第一行一个整数n,代表数列中数的个数。
第二行n个正整数,表示初始状态下数列中的数。
第三行一个整数m,表示有m次操作。
接下来m行每行三个整数k,l,r,k=0表示给[l,r]中的每个数开平方(下取整),k=1表示询问[l,r]中各个数的和。
UPD:注意数据中有可能l>r,所以遇到这种情况请交换l和r。
题解:
以前就做过,因为每一个数至多被开log2log2 x 次就变成1了,所以之前我们可以暴力开方,然后成了1之后就不用管他,直接把跳过它去开放没有变成1的
这一步可以用并查集来搞
代码:
  1 #include<cstdio>
  2 
  3 #include<cstdlib>
  4 
  5 #include<cmath>
  6 
  7 #include<cstring>
  8 
  9 #include<algorithm>
 10 
 11 #include<iostream>
 12 
 13 #include<vector>
 14 
 15 #include<map>
 16 
 17 #include<set>
 18 
 19 #include<queue>
 20 
 21 #include<string>
 22 
 23 #define inf 1000000000
 24 
 25 #define maxn 110000
 26 
 27 #define maxm 500+100
 28 
 29 #define eps 1e-10
 30 
 31 #define ll long long
 32 
 33 #define pa pair<int,int>
 34 
 35 #define for0(i,n) for(int i=0;i<=(n);i++)
 36 
 37 #define for1(i,n) for(int i=1;i<=(n);i++)
 38 
 39 #define for2(i,x,y) for(int i=(x);i<=(y);i++)
 40 
 41 #define for3(i,x,y) for(int i=(x);i>=(y);i--)
 42 
 43 #define mod 1000000007
 44 
 45 using namespace std;
 46 
 47 inline ll read()
 48 
 49 {
 50 
 51     ll x=0,f=1;char ch=getchar();
 52 
 53     while(ch<'0'||ch>'9'){if(ch=='-')f=-1;ch=getchar();}
 54 
 55     while(ch>='0'&&ch<='9'){x=10*x+ch-'0';ch=getchar();}
 56 
 57     return x*f;
 58 
 59 }
 60 int n,m,fa[maxn];
 61 ll s[maxn],a[maxn];
 62 inline void add(int x,ll y)
 63 {
 64     for(;x<=n;x+=x&(-x))s[x]+=y;
 65 }
 66 inline ll sum(int x)
 67 {
 68     ll t=0;
 69     for(;x;x-=x&(-x))t+=s[x];
 70     return t;
 71 }
 72 inline int find(int x){return fa[x]==x?x:fa[x]=find(fa[x]);}
 73 
 74 int main()
 75 
 76 {
 77 
 78     freopen("input.txt","r",stdin);
 79 
 80     freopen("output.txt","w",stdout);
 81 
 82     n=read();
 83     for1(i,n)add(i,a[i]=read());
 84     for1(i,n+1)fa[i]=i;
 85     m=read();
 86     while(m--)
 87     {
 88         int ch=read(),l=read(),r=read();if(l>r)swap(l,r);
 89         if(ch)printf("%lld\n",sum(r)-sum(l-1));
 90         else
 91         {
 92             for(int i=find(l);i<=r;i=find(i+1))
 93             {
 94                 int t=(int)sqrt(a[i]);
 95                 add(i,t-a[i]);
 96                 a[i]=t;
 97                 if(a[i]<=1)fa[i]=find(i+1);
 98             }
 99         }
100     }
101 
102     return 0;
103 
104 }
View Code

 

posted @ 2014-10-23 13:28  ZYF-ZYF  Views(240)  Comments(0Edit  收藏  举报