BZOJ3211花神游历各国

来源:互联网 发布:excel数据怎么求和 编辑:程序博客网 时间:2024/06/10 08:31

211: 花神游历各国

Time Limit: 5 Sec Memory Limit: 128 MB
Submit: 1695 Solved: 646
[Submit][Status][Discuss]
Description
这里写图片描述
Input
这里写图片描述
Output
这里写图片描述
每次x=1时,每行一个整数,表示这次旅行的开心度
Sample Input
4
1 100 5 5
5
1 1 2
2 1 2
1 1 2
2 2 3
1 1 4
Sample Output
101
11
11
HINT
对于100%的数据, n ≤ 100000,m≤200000 ,data[i]非负且小于10^9
一开始想用树状数组理想秒A,但是树状数组不支持区间开根修改,于是用并查集优化,因为10的9次方最多开方5次就变成1,所以f[i]表示>=i的第一个不为1的数的编号。
for (i=find(l);i<=r;i=find(i+1))
如果开根到1以下,需要更改f[i]
if (a[i]<=1) f[i]=find(i+1);

#include<cstdio>#include<cmath>#include<algorithm>using namespace std;long long n,i,t,x,y,z,m,j,k,a[100001],f[100002],c[100001];;long long lowbit(int x){    return x&(-x);}void add(int loc,int value){    int j;    for (j=loc;j<=n;j+=lowbit(j))      c[j]+=value;}long long query(int loc){    int j;    long long ans=0;    for (j=loc;j>=1;j-=lowbit(j))      ans+=c[j];    return ans;}long long find(int x){    if (x==f[x])      return x;    else      {        f[x]=find(f[x]);        return f[x];      }}int main(){    scanf("%lld",&n);    for (i=1;i<=n;i++)      {        scanf("%lld",&a[i]);        add(i,a[i]);        f[i]=i;      }    f[n+1]=n+1;    scanf("%lld",&m);    for (i=1;i<=m;i++)      {        scanf("%lld %lld %lld",&x,&y,&z);        if (x==1)          printf("%lld\n",query(z)-query(y-1));        if (x==2)          for (k=find(y);k<=z;k=find(k+1))            {              t=int(sqrt(a[k]));              add(k,t-a[k]);              a[k]=t;              if (a[k]<=1)                f[k]=find(k+1);             }      }    return 0;}

一开始一直RE,后又Time Limit Exceed,然后又Wrong Answer,我太弱了,一天不跪(DaD3zZ,Yveh,Shallwe,xiaoyimi,稷,DMonster)浑身难受。。。

1 0
原创粉丝点击