NC26143. Master of Graph
描述
"好像有点感觉哦"--小x(Master of Graph)
输入描述
第一行一个数字n,m(1 <= n,m <= 100000,以空格分隔),表示图的点数和边数。
第二行n个数字ai(0 <= ai <= 1000000000000,以空格分隔),表示编号为i的点的权值为ai。
接下来m行,每行两个数字(1 <= u,v <= n),代表编号u的点和编号为v的点之间的无向边
接下来一行,一个数字q(1 <= q <= 100000),表示有q个事件。
接下来q行,每行三个数字"x l r",(1 <= l <= r <= n)。
若x为1,代表小x对编号为l到r所有点的权值进行修改,您无需输出,但修改对后面的事件有影响
若x为0,代表咋胡佬对小x的询问,您需要输出编号l到r所有点的权值和
输出描述
对于每个操作0,输出编号区间[l,r]的和。
示例1
输入:
10 9 3841 45109 42780 10844 63078 15424 7341 8629 56972 10886 1 2 1 3 2 4 2 5 7 4 5 8 6 3 6 9 10 9 6 1 2 10 0 10 10 0 9 10 0 2 3 1 3 3 0 1 10
输出:
23 52 40 4012
C++14(g++5.4) 解法, 执行用时: 139ms, 内存消耗: 7708K, 提交时间: 2019-06-08 16:02:54
#include<bits/stdc++.h> using namespace std; typedef long long ll; const int N=1e5+10; ll A[N]; ll F(ll x){ ll ans=0; while(x)ans+=x%10,x/=10; return ans; } struct SegmentTree{ int l,r,flag;ll sum; #define l(x) Tree[x].l #define r(x) Tree[x].r #define sum(x) Tree[x].sum #define flag(x) Tree[x].flag }Tree[N*4]; void build(int p,int l,int r){ l(p)=l;r(p)=r; if(l==r){sum(p)=A[l];return;} int mid=(l(p)+r(p))/2; build(p*2,l,mid); build(p*2+1,mid+1,r); sum(p)=sum(p*2)+sum(p*2+1); } void change(int p,int l,int r){ if(flag(p))return; if(l(p)==r(p)){ sum(p)=F(sum(p)); if(sum(p)<10)flag(p)=1; return; } int mid=(l(p)+r(p))/2; if(l<=mid)change(p*2,l,r); if(r>mid)change(p*2+1,l,r); sum(p)=sum(p*2)+sum(p*2+1); flag(p)=(flag(p*2)&&flag(p*2+1)); } ll ask(int p,int l,int r){ if(l<=l(p)&&r>=r(p))return sum(p); int mid=(l(p)+r(p))/2;ll val=0; if(l<=mid)val+=ask(p*2,l,r); if(r>mid)val+=ask(p*2+1,l,r); return val; } int main(){ int n,m,x,l,r;cin>>n>>m; for(int i=1;i<=n;++i)scanf("%lld",&A[i]); while(m--){scanf("%d%d",&x,&x);}; build(1,1,n); int Q;cin>>Q;while(Q--){ scanf("%d%d%d",&x,&l,&r); if(x==1)change(1,l,r); else printf("%lld\n",ask(1,l,r)); } }
C++11(clang++ 3.9) 解法, 执行用时: 234ms, 内存消耗: 12704K, 提交时间: 2019-06-09 12:50:30
#include<bits/stdc++.h> #define int long long using namespace std; const int N=1e5+10; int n,m,a,u,v,q; struct node { int l,r,data,flag; }t[N<<2]; int f(int x) { int res=0; while(x) res+=x%10,x/=10; return res; } void push_up(int p) { t[p].data=t[p<<1].data+t[p<<1|1].data; t[p].flag=t[p<<1].flag+t[p<<1|1].flag; } void build(int p,int l,int r) { t[p].l=l,t[p].r=r,t[p].flag=0; if(l==r) { cin>>t[p].data;return ; } int mid=l+r>>1; build(p<<1,l,mid); build(p<<1|1,mid+1,r); push_up(p); } void change(int p,int l,int r) { if(t[p].r-t[p].l+1==t[p].flag) return ; if(t[p].l==t[p].r) { t[p].data=f(t[p].data); if(t[p].data<10) t[p].flag=1; return ; } int mid=t[p].l+t[p].r>>1; if(r<=mid) change(p<<1,l,r); else if(l>mid) change(p<<1|1,l,r); else change(p<<1,l,mid),change(p<<1|1,mid+1,r); push_up(p); } int ask(int p,int l,int r) { if(t[p].l==l&&t[p].r==r) return t[p].data; int mid=t[p].l+t[p].r>>1; if(r<=mid) return ask(p<<1,l,r); else if(l>mid) return ask(p<<1|1,l,r); else return ask(p<<1,l,mid)+ask(p<<1|1,mid+1,r); } signed main() { ios::sync_with_stdio(false); cin>>n>>m; build(1,1,n); for(int i=1;i<=m;i++) cin>>u>>v; cin>>q; while(q--) { int op; cin>>op>>u>>v; if(op) change(1,u,v); else cout<<ask(1,u,v)<<endl; } return 0; }