~~### 小萌新 什么也不会 写得详细一些吧~~
【[BJOI2016]回转寿司】
首先,暴力查找--30分
然后,黑科技---权值线段树
s[]表示前缀和,题目要求的是有多少对(i,j)满足L≤s[j]-s[i]≤R(i<j),变形一下得到s[j]-R≤s[i]≤s[j]-L
因此我们只需要遍历一遍s[]数组,每次对于当前的前缀和s,我们先在线段树上查询区间[s-R,s-L]内有多少个数,然后再把s加入到线段树中,最终求和即可
参考
https://blog.csdn.net/blessLZH0108/article/details/77072022
一般的线段树储存一段线段的信息,
然后这里维护的是单纯的数字,其实本质上没啥差别、、
一般数字比较大,我们就要考虑动态开点,
因为只有当用到时才开,会节省很大空间,
对于这道题是n*log(1e14)
1 #include<bits/stdc++.h>
2 using namespace std;
3 #define ll long long
4 const int maxn=1e5+50;
5 int tot;
6 const ll inf=10000000000+50;
7 ll rt;
8 ll lson[maxn*40*4],rson[maxn*40*4];
9 struct tre
10 {
11 long long v;
12
13 }t[maxn*40*4];
14 ll read()
15 {
16 char ch=getchar();
17 ll f=1,ans=0;
18 while(ch<'0' || ch>'9')
19 {
20 if(ch=='-') f=-1;
21 ch=getchar();
22 }
23 while(ch>='0' && ch<='9')
24 {
25 ans=ans*10+ch-'0';
26 ch=getchar();
27 }
28 return ans*f;
29 }
30 ll query(ll &num,ll l,ll r,ll al,ll ar)
31 {
32 //cout<<"sa";
33 if(!num) num=++tot;
34 //巧妙利用引用赋值左右儿子
35 if(l>=al && r<=ar)
36 {
37 /*cout<<al<<" "<<ar<<" "<<l<<" "<<r<<" ";
38 cout<<num<<" ";
39 cout<<t[num].v<<endl;*/
40 return t[num].v;
41 }
42 ll mid=(l+r)>>1;
43 ll anss=0;
44 if(ar>mid)
45 {
46 anss+=query(rson[num],mid+1,r,al,ar);
47 //传入该节点左右儿子,在后次迭代更新
48 }
49 if(al<=mid)
50 {
51 anss+=query(lson[num],l,mid,al,ar);
52 }
53 return anss;
54
55 }
56 void update(ll &now,ll l,ll r,ll aim)
57 {
58 //cout<<"bug";
59 if(!now)
60 now=++tot;
61 //没开但是要修改,就开一个
62 //
63 if(l==r)
64 {
65 t[now].v++;
66 return;
67 }
68 ll mid=l+r>>1;
69
70 if(aim<=mid)
71 update(lson[now],l,mid,aim);
72 else
73 update(rson[now],mid+1,r,aim);
74
75 t[now].v=t[lson[now]].v+t[rson[now]].v;
76 }
77 int main()
78 {
79
80 ll n,l,r;
81 n=read();
82 l=read();
83 r=read();
84 /* for(int i=1;i<maxn*40;i++)
85 t[i].v=0;*/
86 ll ans=0,num=0;
87 //update(rt,-inf,inf,num);
88 for(int i=1;i<=n;i++)
89 {
90
91 update(rt,-inf,inf,num);
92 num+=read();
93 ans+=query(rt,-inf,inf,num-r,num-l);
94 // num+=read();
95 /*
96 ans+=query(rt,-inf,inf,num-r,num-l);
97 update(rt,-inf,inf,num);*/
98
99 }
100 cout<<ans;
101 return 0;
102 }