bzoj 4034

继续链剖

因为子树在区间上连续,所以记最后一个位置即可

线段树不熟了。。。没注意用LL

  1 #include<bits/stdc++.h>
  2 #define inc(i,l,r) for(i=l;i<=r;i++)
  3 #define dec(i,l,r) for(i=l;i>=r;i--)
  4 #define link(x) for(edge *j=h[x];j;j=j->next)
  5 #define mem(a) memset(a,0,sizeof(a))
  6 #define inf 1e9
  7 #define ll long long
  8 #define succ(x) (1<<x)
  9 #define NM 100000+5
 10 using namespace std;
 11 int read(){
 12     int x=0,f=1;char ch=getchar();
 13     while(!isdigit(ch)){if(ch=='-')f=-1;ch=getchar();}
 14     while(isdigit(ch))x=x*10+ch-'0',ch=getchar();
 15     return x*f;
 16 }
 17 struct info{
 18     ll z,s;
 19     int size;
 20 }T[8*NM],null,_t;
 21 struct edge{
 22     int t;
 23     edge *next;
 24 }e[2*NM],*h[NM],*p=e;
 25 int n,m,f[NM],size[NM],d[NM],top[NM],TOP,a[NM],id[NM],_id[NM],tot,last[NM],son[NM];
 26 int _x,_y,l,r;
 27 info operator+(const info&x,const info&y){
 28     info f;
 29     f.s=x.s+y.s;
 30     f.size=x.size+y.size;
 31     f.z=0;
 32     return f;
 33 }
 34 void add(int x,int y){
 35     p->t=y;p->next=h[x];h[x]=p;p++;
 36 }
 37 void pushdown(int i){
 38     if(T[i].z){
 39         T[i<<1].s+=(ll)T[i<<1].size*T[i].z;T[i<<1].z+=T[i].z;
 40         T[i<<1|1].s+=(ll)T[i<<1|1].size*T[i].z;T[i<<1|1].z+=T[i].z;
 41         T[i].z=0;
 42     }
 43 }
 44 void dfs1(int x){
 45     link(x)
 46     if(!f[j->t]){
 47         f[j->t]=x;
 48         d[j->t]=d[x]+1;
 49         dfs1(j->t);
 50         size[x]+=size[j->t];
 51         if(size[j->t]>size[son[x]])son[x]=j->t;
 52     }
 53     size[x]++;
 54 }
 55 void dfs2(int x){
 56     top[x]=TOP;id[x]=++tot;_id[tot]=x;
 57     if(son[x])dfs2(son[x]);
 58     link(x)
 59     if(!top[j->t])dfs2(TOP=j->t);
 60     last[x]=tot;
 61 }
 62 void build(int i,int x,int y){
 63     int t=x+y>>1;
 64     T[i].size=y-x+1;
 65     if(x==y){
 66         T[i].s=a[_id[x]];
 67         return;
 68     }
 69     build(i<<1,x,t);build(i<<1|1,t+1,y);
 70     T[i]=T[i<<1]+T[i<<1|1];
 71 }
 72 info query(int i,int x,int y){
 73     int t=x+y>>1;
 74     pushdown(i);
 75     if(l<=x&&y<=r)return T[i];
 76     if(y<l||r<x)return null;
 77     return query(i<<1,x,t)+query(i<<1|1,t+1,y);
 78 }
 79 void ch(int i,int x,int y){
 80     int t=x+y>>1;
 81     pushdown(i);
 82     if(l<=x&&y<=r){
 83         T[i].z+=(ll)_y;
 84         T[i].s+=(ll)T[i].size*_y;
 85         return;
 86     }
 87     if(y<l||r<x)return;
 88     ch(i<<1,x,t);ch(i<<1|1,t+1,y);
 89     T[i]=T[i<<1]+T[i<<1|1];
 90 }
 91 int main(){
 92 //    freopen("data.in","r",stdin);
 93     int i;
 94     null.s=0;
 95     n=read();m=read();
 96     inc(i,1,n)a[i]=read();
 97     inc(i,1,n-1){
 98         _x=read();_y=read();
 99         add(_x,_y);add(_y,_x);
100     }
101     f[1]=1;
102     dfs1(1);
103     dfs2(TOP=1);
104     build(1,1,n);
105     while(m--){
106         _y=read();
107         if(_y==3){
108             _x=read();_t.s=0;
109             while(top[_x]!=1){
110                 l=id[top[_x]];r=id[_x];
111                 _t=_t+query(1,1,n);
112                 _x=f[top[_x]];
113             }
114             l=id[1];r=id[_x];
115             _t=_t+query(1,1,n);
116             printf("%lld\n",_t.s);
117         }else{
118             _x=read();l=id[_x];
119             if(_y==1)r=id[_x];else r=last[_x];
120             _y=read();
121             ch(1,1,n);
122         }
123     }
124     return 0;
125 }
View Code

 

转载于:https://www.cnblogs.com/onlyRP/p/5041702.html

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
BZOJ 2908 题目是一个数据下载任务。这个任务要求下载指定的数据文件,并统计文件中小于等于给定整数的数字个数。 为了完成这个任务,首先需要选择一个合适的网址来下载文件。我们可以使用一个网络爬虫库,如Python中的Requests库,来帮助我们完成文件下载的操作。 首先,我们需要使用Requests库中的get()方法来访问目标网址,并将目标文件下载到我们的本地计算机中。可以使用以下代码实现文件下载: ```python import requests url = '目标文件的网址' response = requests.get(url) with open('本地保存文件的路径', 'wb') as file: file.write(response.content) ``` 下载完成后,我们可以使用Python内置的open()函数打开已下载的文件,并按行读取文件内容。可以使用以下代码实现文件内容读取: ```python count = 0 with open('本地保存文件的路径', 'r') as file: for line in file: # 在这里实现对每一行数据的判断 # 如果小于等于给定整数,count 加 1 # 否则,不进行任何操作 ``` 在每一行的处理过程中,我们可以使用split()方法将一行数据分割成多个字符串,并使用int()函数将其转换为整数。然后,我们可以将该整数与给定整数进行比较,以判断是否小于等于给定整数。 最后,我们可以将统计结果打印出来,以满足题目的要求。 综上所述,以上是关于解决 BZOJ 2908 数据下载任务的简要步骤和代码实现。 希望对您有所帮助。

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值