将y坐标离散化 第i段为区间\([raw(i),raw(i+1)]\) \(c[i]\)记录扫描线上第i段被覆盖的次数
unique返回去重后的尾迭代器,是去重之后末尾元素的下一个位置
珂朵莉树(ODT)
使一整段区间内的东西变得一样,数据随机。
定义节点
表示区间\([l,r]\)全是数v
struct node{
int l,r,;
mutable ll v;
node{int L,int R=-1,ll V=0}:l(L),r(R),v(V){}
bool operator<(const node&X)const{return l<X.l;}
};
#define iter set<node>::iterator
iter split(int pos){
iter it=s.lower_bound(node(pos));
}
\(QAQ\)我又写炸了一个新知识的!!! 今天不宜学习新东西啊啊啊啊啊啊啊啊啊啊啊啊
蜜汁CE
#include
using namespace std;
#define ll long long
#define Max(x,y) ((x)>(y)?(x):(y))
#define Min(x,y) ((x)<(y)?(x):(y))
#define Abs(x) ((x)<0?-(x):(x))
#define ls (o<<1)
#define rs (o<<1|1)
const int N=1e5+5,M=100+5,inf=0x3f3f3f3f;
int n,m;
ll seed,mx,a[N];
struct node{
int l,r;
mutable ll k;
node(int L,int R=-1,ll K=0):l(L),r(R),k(K){}
bool operator<(const node&X)const{return l::iterator
sets;
iter split(int pos){
iter it=s.lower_bound(node(pos));
if(it!=s.end()&&it->l==pos) return it;
--it;
int l=it->l,r=it->r;ll k=it->k;
s.erase(it),s.insert(node(l,pos-1,k));
return s.insert(node(pos,r,k)).first;
}
void assign_val(int l,int r,ll k){
iter itl=split(l),itr=split(r+1);
s.erase(itl,itr),s.insert(node(l,r,k));
}
void add(int l,int r,ll k){
iter itl=split(l),itr=split(r+1);
for(;itl!=itr;++itl) itl->k+=k;
}
typedef pairpii;
ll ranks(int l,int r,int k){
vectorv;
iter itl=split(l),itr=split(r+1);
for(;itl!=itr;++itl) v.push_back(make_pair(itl->k,itl->r-itl->l+1));
sort(v.begin(),v.end());
for(vector::iterator it=v.begin();it!=v.end();++it){
k-=it->second;
if(k<=0) return it->first;
}
}
ll qpow(ll a,ll b,ll P){
ll res=1;a%=P;
while(b){
if(b&1) res=(res*a)%P;
a=(a*a)%P,b>>=1;
}
return res;
}
ll sum(int l,int r,int x,int P){
iter itl=split(l),itr=split(r+1);
ll res=0;
for(;itl!=itr;++itl)
res=(res+(ll)(itl->r-itl->l+1)*qpow(itl->k,(ll)x,(ll)P))%P;
return res;
}
ll rd(){
ll ret = seed;
seed=(seed*7+13)%((int)1e9+7);
return ret;
}
int main(){
freopen("in.txt","r",stdin);
scanf("%d%d%lld%lld",&n,&m,&seed,&mx);
for(int i=1;i<=n;++i) a[i]=(rd()%mx)+1,s.insert(node(i,i,a[i]));
s.insert(node(n+1,n+1,0));
for(int i=1,opt,l,r,x,y;i<=m;++i){
opt=(rd()%4)+1,l=(rd()%n)+1,r=(rd()%n)+1;
if(l>r) swap(l,r) ;
if(opt==3) x=(rd()%(r-l+1))+1;
else x=(rd()%mx)+1;
if(opt==4) y=(rd()%mx)+1;
if(opt==1) add(l,r,x);
else if(opt==2) assign_val(l,r,x);
else if(opt==3) printf("%lld\n",ranks(l,r,x));
else printf("%lld\n",sum(l,r,x,y));
}
return 0;
}
临时开一个数组 利用new关键字来实现
临时申明一个大小为size的数组Type *name=new Type[size]
使用完动态数组后将其销毁 delete [] name
==只是这些都是指针来实现 看着有点淡淡的忧伤
链表 - 插入
首先将节点p的nxt指向插入之后的下一个节点 然后再将前一个节点的nxt指向p
p->nxt=q->nxt; q->nxt=p;
链表 - 删除
直接将要删除的前一个节点的nxt指向待删节点的nxt即可p->nxt=p->nxt->nxt
双向链表
不仅记录当前元素的下一个元素nxt 还有当前元素的上一个元素prev
结构体:
struct list{
type date;
list * prev,* nxt;
}
插入
p->nxt=q->nxt,p->prev=q;
q->nxt->prev=p,q->nxt=p;
删除:
p->nxt=p->nxt->nxt,p->nxt->prev=p;
时间复杂度==咕咕咕咕见笔记本吧