BZOJ 5395--[Ynoi2016]谁的梦(STL&容斥)

时间:2023-12-22 09:00:32

5395: [Ynoi2016]谁的梦

Time Limit: 80 Sec  Memory Limit: 128 MB
Submit: 22  Solved: 7
[Submit][Status][Discuss]

Description

6.373
世界是独立于我的意志的。
6.374
就算我们所期望的全部的事情都发生了
这果然也只能说是命运的恩惠吧。
要问为什么,那是因为意志和世界之间
能够保证这件事的逻辑性的关联并不存在
Ludwig Josef Johann Wittgenstein [逻辑哲学论]
自从双胞胎的哥哥过世起,已经过了多久了呢…
从那时起,我一直保存着能够布偶。
在那以后的我只是个影子…而这个布偶才是我…
这样也并没有什么不好。
我觉得只要现在的我消失掉就行了…
那两个人却救了这样的我。
一个是由岐姐…
她又来到了我的身边…
带着皆守哥…回到了我们的身边…
水上由岐姐姐…温柔的姐姐
曾经非常喜欢皆守哥的人……
 BZOJ 5395--[Ynoi2016]谁的梦(STL&容斥)
回去的路上…
平时不会经过的坡道…
在登上那个坡道的途中…
我看到了夜晚的太阳。
明明就在附近,却一直不知道的巨大的向日葵。
夜露使它的绒毛泛出了白光。
碧蓝的月光和黄色的向日葵…
就好像太阳和月亮的立场反过来一样…
原本是那么耀眼的太阳在地上,只能在其背后下发光的月亮在天上…
黄色的向日葵被染成了碧蓝色。
那副样子虽然很美丽…
努力绽放的向日葵,看起来反而是柔弱的存在。
在夜里向天空伸展的向日葵…
我在车内一直追寻着它的身影…
被夜晚的月光映照着的太阳。
被染成碧蓝色的太阳…
它的身影…我一直追寻着……
 BZOJ 5395--[Ynoi2016]谁的梦(STL&容斥)
被月光照亮的天台上…
一个人影…
明明只是一个人影…却好像…在和什么东西对峙着一样…
皆守哥…
月下的立像,一个人影。
胸口在风中闪烁。
放在胸前的手里的是…那时的小刀。
和七年前同样的姿势。
唯一不同的是,那里的人影只有一个。
那把小刀,好像是被他自己刺入体内。
 BZOJ 5395--[Ynoi2016]谁的梦(STL&容斥)
是诅咒…
这是理所当然的事…
那并不是什么精神病…
那是诅咒…
下在幸存的我们身上的…诅咒…
说不定,不仅仅是卓司哥…连由岐姐也在诅咒我们…
所以变成这种结果…
哥哥刺向了自己的胸口…
破坏了我的半身…
然后…还要把很多人送回到天空…
回归天空的日子。
交还灵魂的日子。
那一天,卓司哥对我做的事情。
杀了由岐姐的…那个行为…
他想要再一次实行…
这次…和很多人一起…
 BZOJ 5395--[Ynoi2016]谁的梦(STL&容斥)
不是…
那是…我啊…
是那个…坡道的事情啊…
两个人一起看到向日葵的…那个坡道…
…我说要爬上那个坡道…要去寻找爸爸的灵魂…
我想,如果到了那个坡道的前方,就能取回爸爸的灵魂…爸爸就会复生的…
如果越过向日葵之路…向着向日葵所朝向的天空延伸的…那个大大的坡道的话…大概,就会有爸爸的灵魂…
爸爸的故乡的…大大的坡道…
 BZOJ 5395--[Ynoi2016]谁的梦(STL&容斥)
哥哥的身体浮在空中…
我无言地跳了出去。
啊啊…是这样啊…
由岐姐也是这种心情啊…
并没有什么道理可言…
只是因为喜欢的人向着天空跳下去了…
我想要抓住那个身体…
我--
您正在打galgame,突然断电了,于是您跑去物管处问,结果发现是由于一个光头踢了变压器一脚导致的,
可能还要修很久,于是您决定想一个之前见过的数据结构题:
定义一个序列的权值为不同数字的个数,例如 [1,2,3,3] 权值为 3
现在有n个序列,我们在每个序列里面选一个连续非空子串,拼接起来,求所有选法得到的序列的权值之和
如果一个序列能通过多种方法被选择出来,那么计算多次
本题带修改操作,格式请参考输入格式
由于结果可能过大,请输出答案 mod 19260817 的结果

Input

第一行两个数 n,m,表示有n个序列,m次修改
然后n个数,第i个数是leni,表示第i个序列的长度
之后n行,每行leni个数,表示第i个序列
之后m行,每行三个数x,y,z表示将第x个序列的第y个元素改为z
1 <= n,m <= 100000,序列中的元素均为 32 位整型数,leni的和 <= 100000
共53组数据

Output

输出m + 1行,依次表示初始局面以及每次修改后的答案。

Sample Input

2 5
6 6
1 3 1 1 3 2
2 3 3 2 1 1
1 1 1
1 1 2
1 1 2
1 1 1
1 1 1

Sample Output

1158
1158
1168
1168
1158
1158

题目链接:

    http://www.lydsy.com/JudgeOnline/problem.php?id=5395

Solution

  少女的等待故事。

  爱慕哥哥的少女,她坚信着哥哥的承诺,在向日葵的坡道下等待着他的回归。

  居然在ynoi上抢到rk1.。。感觉很神奇。。。果然是因为我是素学家吗QAQ

  BZOJ 5395--[Ynoi2016]谁的梦(STL&容斥)

  然后是题解。。。

  首先发现每种颜色对答案的贡献都是独立的。。。

  对于某一种颜色,直接算在多少个序列中出现比较困难。。

  所以考虑用总数减去没有出现的次数。。

  然后对每一行统计答案,然后乘法原理。。。遍历的时候要用set。。。

  单点修改只会影响某两种颜色的贡献,暴力修改即可。。

代码

#include<iostream>
#include<cstdio>
#include<set>
#include<map>
#define LL long long
using namespace std;
inline int read(){
LL x=0,f=1;char ch=getchar();
while(ch<'0'||ch>'9'){if(ch=='-')f=-1;ch=getchar();}
while(ch>='0'&&ch<='9'){x=x*10+ch-'0';ch=getchar();}
return x*f;
}
inline void Out(LL a){
if(a>9) Out(a/10);
putchar(a%10+'0');
}
const LL N=200050;
const LL mod=19260817;
LL n,m,tot,num,LEN,NY;
LL a[N],hang[N],lie[N],len[N],hed[N];
LL sum[N],nsum[N],ans[N],zer[N];
set<LL> S[N];
map<LL,LL>lsh;
map<LL,LL> mp[N],c[N];
LL res=0,ss;
LL pow(LL x,LL y){
LL re=1;
while(y){
if(y&1) re=re*x%mod;
x=x*x%mod;y>>=1;
}
return re;
}
LL get(LL u,LL v){
LL l=1,r=tot;
while(l!=r){
LL mid=l+r>>1;
if(hang[mid]<u||(hang[mid]==u&&lie[mid]<v)) l=mid+1;
else r=mid;
}
return l;
}
int main(){
NY=pow((LL)2,mod-2);
n=read();m=read();ss=1;
for(LL i=1;i<=n;++i){
len[i]=read();
ss=ss*(LL)len[i]%mod*(LL)(len[i]+1)%mod*NY%mod;
LEN+=len[i];
}
//cout<<ss<<endl;
sum[0]=nsum[0]=1;
for(LL i=1;i<=n;++i){
sum[i]=(LL)(len[i]+1)*(LL)len[i]/(LL)2%mod;
sum[i]=sum[i]*sum[i-1]%mod;
nsum[i]=pow(sum[i],mod-2);
for(LL j=1;j<=len[i];++j){
a[++tot]=read();
if(!lsh[a[tot]]) {
lsh[a[tot]]=++num;
}
a[tot]=lsh[a[tot]];
S[a[tot]].insert(tot);
hang[tot]=i;lie[tot]=j;
}
}
LL u,v,w,x;
for(LL i=1;i<=num;++i){
u=0;v=0;ans[i]=1;
for(set<LL>::iterator it=S[i].begin();it!=S[i].end();++it){
//cout<<u<<" "<<v<<endl;
x=*it;
if(u==0){
ans[i]=ans[i]*sum[hang[x]-1]%mod;
mp[i][hang[x]]+=(LL)(lie[x]-1)*(LL)lie[x]/(LL)2;
}
else if(u!=hang[x]){
mp[i][u]+=(LL)(len[u]-v)*(LL)(len[u]-v+1)/(LL)2;
if(mp[i][u]>0) ans[i]=ans[i]*mp[i][u]%mod;
else zer[i]++;
ans[i]=ans[i]*sum[hang[x]-1]%mod*nsum[u]%mod;
mp[i][hang[x]]+=(LL)(lie[x]-1)*(LL)lie[x]/(LL)2;
}
else mp[i][hang[x]]+=(LL)(lie[x]-v-1)*(LL)(lie[x]-v)/2;
u=hang[x];v=lie[x];
}
mp[i][u]+=(LL)(len[u]-v)*(LL)(len[u]-v+1)/(LL)2;
if(mp[i][u]>0) ans[i]=ans[i]*mp[i][u]%mod;
else zer[i]++;
ans[i]=ans[i]*sum[n]%mod*nsum[u]%mod;
if(zer[i]>0) res+=ss;
else res+=ss-ans[i];
//cout<<ss<<" "<<ans[i]<<endl;
}
res=(res%mod+mod)%mod;
Out(res);puts("");
set<LL>::iterator l,r;
LL L,R,lx,rx;
while(m--){
u=read();v=read();w=read();
x=get(u,v);
l=S[a[x]].lower_bound(x);
r=l;
if(l==S[a[x]].begin()) L=0;
else {
--l;L=*l;
if(hang[L]!=u) L=0;
else L=lie[L];
}
++r;
if(r==S[a[x]].end()) R=len[u];
else{
R=(*r);
if(hang[R]!=u) R=len[u];
else R=lie[R]-1;
}
if(zer[a[x]]>0) res-=ss;
else res-=ss-ans[a[x]];
if(mp[a[x]][u]>0)ans[a[x]]=ans[a[x]]*pow(mp[a[x]][u],mod-2)%mod;
else --zer[a[x]];
mp[a[x]][u]-=(LL)(R-v)*(R-v+1)/2+(LL)(v-1-L)*(v-L)/2;
mp[a[x]][u]+=(LL)(R-L)*(R-L+1)/2;
if(mp[a[x]][u]>0) ans[a[x]]=ans[a[x]]*mp[a[x]][u]%mod;
else ++zer[a[x]];
if(zer[a[x]]>0) res+=ss;
else res+=ss-ans[a[x]];
S[a[x]].erase(x);
if(!lsh[w]){
lsh[w]=++num;
ans[num]=sum[n];
}
w=lsh[w];
a[x]=w;
S[w].insert(x);
l=S[a[x]].lower_bound(x);
r=l;
if(l==S[a[x]].begin()) L=0;
else {
--l;L=*l;
if(hang[L]!=u) L=0;
else L=lie[L];
}
++r;
if(r==S[a[x]].end()) R=len[u];
else{
R=(*r);
if(hang[R]!=u) R=len[u];
else R=lie[R]-1;
}
if(R==len[u]&&L==0) mp[w][u]=(LL)(len[u]+1)*(LL)len[u]/2;
if(zer[a[x]]>0) res-=ss;
else res-=ss-ans[a[x]];
if(mp[a[x]][u]>0)ans[a[x]]=ans[a[x]]*pow(mp[a[x]][u],mod-2)%mod;
else --zer[a[x]];
mp[a[x]][u]-=(LL)(R-L)*(R-L+1)/2;
mp[a[x]][u]+=(LL)(R-v)*(R-v+1)/2+(LL)(v-1-L)*(v-L)/2;
if(mp[a[x]][u]>0) ans[a[x]]=ans[a[x]]*mp[a[x]][u]%mod;
else ++zer[a[x]];
if(zer[a[x]]>0) res+=ss;
else res+=ss-ans[a[x]];
res=(res%mod+mod)%mod;
Out(res);puts("");
}
return 0;
}

  

  

This passage is made by Iscream-2001.