题意
给你一个数列a1,a2,a3......an,数列所有值的初始值为0,有三种操作:
操作1:将区间[l,r]中所有数加c
操作2:将区间[l,r]中所有数变成c
操作3:查询区间[l,r]中,
的值
最终答案对1e4+7取余就行了。
题解:
这个题有两个做法,一种是明显的用线段树维护就行,另一种就是用珂朵莉树,可以说是板子题了。
其实正确做法是用线段树维护,珂朵莉树的做法可以专门通过数据卡掉,而且题目没有保障数据是随机生成的,所以应该是不能过的,但是数据可能有点弱(但把我的线段树给卡掉了QAQ),因此也可以用珂朵莉树做。
用线段树求的话会有点麻烦,不过还是可以做的,具体过程请参考hdu4578,这个题的强化版本(我觉得魔改的题面,毕竟就多了一个乘法的操作),也可以参考我写的那个题的题解:https://blog.csdn.net/qq_43472263/article/details/103597326
珂朵莉树的代码如下(其实就是暴力,妙用了set的平衡树实现的,关于这个算法可以参考:珂朵莉树)
#include<iostream> #include<algorithm> #include<cmath> #include<cstring> #include<cstdio> #include<cstdlib> #include<vector> #include<map> #include<set> #include<stack> #include<queue> #define PI atan(1.0)*4 #define E 2.718281828 #define rp(i,s,t) for (i = (s); i <= (t); i++) #define RP(i,s,t) for (i = (t); i >= (s); i--) #define ll long long #define ull unsigned long long #define mst(a,b) memset(a,b,sizeof(a)) #define lson l,m,rt<<1 #define rson m+1,r,rt<<1|1 using namespace std; inline int read() { int a=0,b=1; char c=getchar(); while(c<'0'||c>'9') { if(c=='-') b=-1; c=getchar(); } while(c>='0'&&c<='9') { a=(a<<3)+(a<<1)+c-'0'; c=getchar(); } return a*b; } struct node{ int l,r; mutable int v; node(int l,int r=-1,int v=0):l(l),r(r),v(v){} bool operator <(const node &others) const{ return l<others.l; } }; const int mod=1e4+7; set<node> s; #define IT set<node>::iterator IT split(int pos){ IT it=s.lower_bound(node(pos)); if(it!=s.end()&&it->l==pos) return it; --it; int L=it->l,R=it->r; int V=it->v; s.erase(it); s.insert(node(L,pos-1,V)); return s.insert(node(pos,R,V)).first; } void update(int l,int r,int val){ IT itr=split(r+1),itl=split(l); s.erase(itl,itr); s.insert(node(l,r,val)); } void add(int l,int r,int val){ IT itr=split(r+1),itl=split(l); for(;itl!=itr;itl++) itl->v=(val+itl->v)%mod; } int quick_mod(int a,int b){ int res=1; while(b){ if(b&1) res=(res*a)%mod; a=(a*a)%mod; b>>=1; } return res%mod; } int query(int l,int r,int k){ IT itr=split(r+1),itl=split(l); int ans=0; for(;itl!=itr;itl++) ans=(ans+quick_mod(itl->v,k)*(itl->r-itl->l+1)%mod)%mod; return ans%mod; } // #define pii pair<int,int> // int Kth(int l,int r,int k){ // vector<pii> v; // IT itr=split(r+1),itl=split(l); // for(;itl!=itr;itl++) v.push_back(make_pair(itl->v,itl->r-itl->l+1)); // sort(v.begin(),v.end()); // for(vector<pii>::iterator it=v.begin();it!=v.end();it++){ // k-=it->second; // if(k<=0) return it->first; // } // return -1; // } int main(){ int n,m,i; while(~scanf("%d%d",&n,&m)){ if(!n&&!m) break; s.clear(); rp(i,1,n) s.insert(node(i,i,0)); while(m--){ int opt=read(),l=read(),r=read(),k=read(); if(opt==1) add(l,r,k); else if(opt==2) update(l,r,k); else printf("%d\n",query(l,r,k)%mod); } } return 0; }