魔法学院第一题(第二个魔法学院不会写!等大佬写稿) 我用的线段树写的 我感觉用树状数组更好写很多,但是没尝试,哎 加一个懒标记 完美, 线段树的话 其实维护的内容很少 就,,就一个sum和一个懒标记(sum也可以最后pushdown的时候 再维护,也可以不维护最后直接累加求和) 底下这个代码是过不了的 因为没有对n=1的时候特判断 可以自行加上去 然后交可以a啦
#define ll long long
#define mem(a) memset(a,0,sizeof(a))
#define IOS ios::sync_with_stdio(false);cin.tie(0);cout.tie(0)
#define inf 0x3f3f3f3f
#define sf(n) scanf("%d", &n)
// #define endl '\n'
#define cyes cout<<"yes"<<endl
#define debug(x) cout<<"-----"<<x<<endl
//#define ll long long
#define fo(a,b,c) for(int a=b;a<=c;a++)
//#define maxn 1000000
#define mod 9901
#define int ll
using namespace std;
int pre=0;
int read() //快读
{
int x=0,f=1;
char c=getchar();
while(c<'0'||c>'9')
{
if(c=='-') f=-1;
c=getchar();
}
while(c>='0'&&c<='9')
{
x=x*10+c-'0';
c=getchar();
}
return x*f;
}
struct tree
{
int l,r;
int sum;
int c;
} tr[100010*4];
int in[1000010];
void push(tree &a,tree &b,tree &c)
{
a.sum=b.sum+c.sum;
}
void push(int n)
{
push(tr[n],tr[n<<1],tr[n<<1|1]);
}
void build(int u,int l,int r)
{
if(l==r)tr[u]= {l,r,in[l],in[l]};
else
{
tr[u]= {l,r};
int mid=l+r>>1;
build(u<<1|1,mid+1,r);
build(u<<1,l,mid);
push(u);
}
}
void change(int u,int lx,int rx, int v)
{
if(tr[u].l>=lx&&tr[u].r<=rx)
{
tr[u].c=max(tr[u].c,v);
}
else
{
int mid=tr[u].l+tr[u].r>>1;
if(lx<=mid) change(u<<1,lx,rx,v);
if(rx>mid) change(u<<1|1,lx,rx,v);
}
}
void pushdown(int u)
{
if(tr[u].l==tr[u].r) tr[u].sum=max(tr[u].c,tr[u].sum);
else
{
auto &root=tr[u],&left=tr[u<<1],&right=tr[u<<1|1];
left.c=max(root.c,left.c);
right.c=max(root.c,right.c);
pushdown(u<<1),pushdown(u<<1|1);
push(u);
}
}
signed main()
{
int n,m;
n=read();
m=read();
char c;
for(int i=1; i<=n; ++i)
{
scanf("%c",&c);
in[i]=c;
}
int a,l,r;
build(1,1,n);
while(m--)
{
l=read();
r=read();
scanf("%c",&c);
a=c;
change(1,l,r,a);
}
pushdown(1);
printf("%lld",tr[1].sum);
return 0;
}