rt,用线段树暴力修改,复杂度均摊下来应该是 nlogn2 吧,应该能过的。是常数大了还是被卡了?
#include<bits/stdc++.h>
#define int long long
using namespace std;
inline int read()
{
int res=0,f=1;char c=getchar();
while(c<'0'||c>'9'){if(c=='-')f=-1;c=getchar();}
while(c>='0'&&c<='9'){res=(res<<1)+(res<<3)+(c^48);c=getchar();}
return res*f;
}
#define ls (root<<1)
#define rs (root<<1|1)
#define mid ((t[root].l+t[root].r)>>1)
struct segt
{
int l,r,val,tag;
}t[1145141<<2];
inline void down(int root)
{
t[ls].tag+=t[root].tag;
t[rs].tag+=t[root].tag;
t[ls].val+=(t[ls].r-t[ls].l+1)*t[root].tag;
t[rs].val+=(t[rs].r-t[rs].l+1)*t[root].tag;
t[root].tag=0;
}
void bld(int l,int r,int root)
{
t[root].l=l;
t[root].r=r;
if(l==r)
return;
bld(l,mid,ls);
bld(mid+1,r,rs);
}
void addt(int x,int y,int root,int k)
{
if(t[root].l>=x&&t[root].r<=y)
{
t[root].tag+=k;
t[root].val+=(t[root].r-t[root].l+1)*k;
return;
}
if(t[root].tag)
down(root);
if(x<=mid)
addt(x,y,ls,k);
if(y>mid)
addt(x,y,rs,k);
t[root].val=t[ls].val+t[rs].val;
}
int query(int x,int root)
{
if(t[root].l==t[root].r)
return t[root].val;
if(t[root].tag)
down(root);
int res=0;
if(x<=mid)
res+=query(x,ls);
else
res+=query(x,rs);
return res;
}
//------------以上为线段树-----------
//------------以下为odt--------------
struct node
{
int l,r;
mutable int val;
node(int l,int r=0,int val=0):l(l),r(r),val(val){};
bool operator<(const node &a)const
{
return l<a.l;
}
};
set<node>odt;
inline set<node>::iterator split(int pos)
{
set<node>::iterator it=odt.lower_bound(node(pos));
if(it!=odt.end()&&it->l==pos)
return it;
--it;
if(it->r<pos)
return odt.end();
int l=it->l;
int r=it->r;
int val=it->val;
odt.erase(it);
odt.insert(node(l,pos-1,val));
return odt.insert(node(pos,r,val)).first;
}
inline void assign(int l,int r,int x)
{
set<node>::iterator itr=split(r+1),itl=split(l);
odt.erase(itl,itr);
odt.insert(node(l,r,x));
}
inline void add(int c,int x)
{
for(set<node>::iterator it=odt.begin();it!=odt.end();it++)
if(it->val==c)
addt(it->l,it->r,1,x);
}
int n,q;
signed main()
{
n=read(),q=read();
bld(1,n,1);
odt.insert(node(1,n,1));
while(q--)
{
string op;
int l,r,c;
cin>>op;
if(op=="Color")
{
l=read(),r=read(),c=read();
assign(l,r,c);
}
else if(op=="Add")
{
l=read(),c=read();
add(l,c);
}
else
{
l=read();
printf("%lld\n",query(l,1));
}
}
}