题解:
这题看起来很难。。。但是实际上并没有想象中的那么难
第一眼看上去不会求导公式怎么办?不要紧,题目背景非常良心的给出了题目中的导数计算公式
求完导合并同类项很恶心怎么办?不要紧,样例解释说明了不需要合并同类项(然后有许多人因为这个爆〇了)
一看这种题目形式明显就是大数据结构,外面的序列明显线段树维护,次数也可以用线段树,但是线段树套线段树容易MLE;
所以用树状数组套线段树实现
具体就是以1~n为下标建线段树,外面用树状数组维护次数,每次在树状数组上查询即可
写完过样例直接1A就是爽
代码:
1 #include<algorithm>
2 #include<iostream>
3 #include<cstring>
4 #include<cstdio>
5 #include<cmath>
6 #include<queue>
7 #define inf 2147483647
8 #define eps 1e-9
9 #define lb(x) (x&-x)
10 using namespace std;
11 typedef long long ll;
12 const int N=1000000,bit=524288;
13 struct node{
14 int num,ls,rs;
15 ll v;
16 }t[10000001];
17 int n,m,ans=0,op,l,r,tot=0,rts[1000001];
18 int TheseNumbersDoNotMakeAnySense;
19 ll s;
20 void newn(int &u){
21 if(!u)u=++tot;
22 }
23 void pd(int u,int l,int r){
24 if(t[u].num){
25 int mid=(l+r)/2;
26 newn(t[u].ls);
27 newn(t[u].rs);
28 t[t[u].ls].num+=t[u].num;
29 t[t[u].ls].v+=t[u].num*(mid-l+1);
30 t[t[u].rs].num+=t[u].num;
31 t[t[u].rs].v+=t[u].num*(r-mid);
32 t[u].num=0;
33 }
34 }
35 void updata(int l,int r,int &u,int L,int R,int v){
36 newn(u);
37 if(L<=l&&r<=R){
38 t[u].num+=v;
39 t[u].v+=v*(r-l+1);
40 return;
41 }
42 int mid=(l+r)/2;
43 pd(u,l,r);
44 if(L<=mid)updata(l,mid,t[u].ls,L,R,v);
45 if(mid<R)updata(mid+1,r,t[u].rs,L,R,v);
46 t[u].v=t[t[u].ls].v+t[t[u].rs].v;
47 }
48 int query(int l,int r,int u,int L,int R){
49 if(!u)return 0;
50 if(L<=l&&r<=R){
51 return t[u].v;
52 }
53 int mid=(l+r)/2,ret=0;
54 pd(u,l,r);
55 if(L<=mid)ret=query(l,mid,t[u].ls,L,R);
56 if(mid<R)ret+=query(mid+1,r,t[u].rs,L,R);
57 return ret;
58 }
59 void ins(int l,int r,int s){
60 for(;s<=N;s+=lb(s)){
61 updata(1,n,rts[s],l,r,1);
62 }
63 }
64 ll ask(int l,int r,int s){
65 ll ret=0;
66 for(;s;s-=lb(s)){
67 ret+=query(1,n,rts[s],l,r);
68 }
69 return ret;
70 }
71 void work(int l,int r,ll s){
72 ll ret=ask(l,r,N),tmp=0;
73 if(ret<=s){
74 printf("1 %lld
",ret);
75 ans=1;
76 return;
77 }
78 s=ret-s;
79 for(int bt=bit;bt;bt/=2){
80 if(tmp+bt<=N){
81 int q=query(1,n,rts[tmp+bt],l,r);
82 //printf("%lld %lld %lld
",tmp,bt,q);
83 if(s>q)s-=q,tmp+=bt;
84 }
85 }
86 ll rt=ask(l,r,tmp+1);
87 rt=ret-rt;
88 printf("%lld %lld
",tmp+2,rt);
89 ans=tmp+2;
90 }
91 int main(){
92 scanf("%d%d",&n,&m);
93 for(int i=1;i<=n;i++){
94 scanf("%d",&TheseNumbersDoNotMakeAnySense);
95 }
96 for(int i=1;i<=m;i++){
97 scanf("%d%d%d%lld",&op,&l,&r,&s);
98 if(op==0){
99 s^=ans;
100 ins(l,r,s);
101 }else{
102 work(l,r,s);
103 }
104 }
105 return 0;
106 }