5 3
1 2 3 4 5
1 3
2 3
1 5
52
一个线段树+单点修改+区间查询
1 #include<iostream> 2 #include<cstdio> 3 #define ll long long 4 using namespace std; 5 struct sb 6 { 7 ll l,r,num,id; 8 }t[1000001]; 9 ll n,m; 10 ll maxx,wz; 11 inline long long read() 12 { 13 char c;int d=1;long long f=0; 14 while(c=getchar(),!isdigit(c))if(c==45)d=-1;f=(f<<3)+(f<<1)+c-48; 15 while(c=getchar(),isdigit(c)) f=(f<<3)+(f<<1)+c-48; 16 return d*f; 17 } 18 void up(ll k) //比较区间最大值 19 { 20 if (t[k*2].num>t[k*2+1].num) 21 { 22 t[k].num=t[k*2].num; 23 t[k].id=t[k*2].id; 24 } 25 else 26 { 27 t[k].num=t[k*2+1].num; 28 t[k].id=t[k*2+1].id; 29 } 30 return; 31 } 32 void build(ll a,ll b,ll k) //建树 33 { 34 t[k].l=a; t[k].r=b; 35 if (a==b) 36 { 37 t[k].num=read(); 38 t[k].id=t[k].l; 39 return; 40 } 41 ll mid=(a+b)/2; 42 build(a,mid,2*k); 43 build(mid+1,b,2*k+1); 44 up(k); 45 } 46 void find(ll a,ll b,ll k) //查找 47 { 48 if (t[k].l==a&&t[k].r==b) 49 { 50 if (t[k].num>maxx) 51 { 52 maxx=t[k].num; 53 wz=t[k].id; 54 } 55 return; 56 } 57 ll mid=(t[k].l+t[k].r)/2; 58 if (b<=mid) find(a,b,k*2); 59 else if (a>mid) find(a,b,k*2+1); 60 else { 61 find(a,mid,k*2); 62 find(mid+1,b,k*2+1); 63 } 64 } 65 void change(ll wz,ll k) //修改值 66 { 67 if (t[k].l==t[k].r) 68 { 69 t[k].num=0; 70 t[k].id=0; 71 return; 72 } 73 ll mid=(t[k].l+t[k].r)/2; 74 if (mid>=wz) change(wz,k*2); 75 else if (mid<wz) change(wz,k*2+1); 76 up(k); 77 } 78 int main () 79 { 80 cin>>n>>m; 81 build(1,n,1); 82 ll ans=0; 83 for (ll i=1,x,y;i<=m;i++) 84 { 85 x=read(); 86 y=read(); 87 maxx=0;wz; 88 find(x,y,1); 89 change(wz,1); 90 ans+=(x+y)*maxx; 91 ans%=2011; 92 } 93 cout<<ans; 94 }
原文:https://www.cnblogs.com/zjzjzj/p/10461400.html