题解 P9994
前言
咋大家都不是单根?
思路
看着就不太能
那么对于一个点数
对于点数
接下来是如何计算
考虑到一共只有
总时间复杂度
代码
// Problem: P9994 [Ynoi Easy Round 2024] TEST_132
// Contest: Luogu
// URL: https://www.luogu.com.cn/problem/P9994
// Memory Limit: 512 MB
// Time Limit: 12000 ms
//
// Powered by CP Editor (https://cpeditor.org)
//泥の分際で私だけの大切を奪おうだなん
#include<bits/stdc++.h>
using namespace std;
inline int read(){
int s=0,w=1;
char ch=getchar();
while(ch<'0'||ch>'9'){if(ch=='-')w=-1;ch=getchar();}
while(ch>='0'&&ch<='9') s=s*10+ch-'0',ch=getchar();
return s*w;
}
const int p=1e9+7,q=1e9+6,B=2000;
struct multi
{
int a0[256],a1[256],a2[256],a3[256];
void init(int b)
{
a0[0]=a1[0]=a2[0]=a3[0]=1;
for(int i=1; i<256; ++i) a0[i]=1ll*a0[i-1]*b%p;
b=1ll*b*a0[255]%p;
for(int i=1; i<256; ++i) a1[i]=1ll*a1[i-1]*b%p;
b=1ll*b*a1[255]%p;
for(int i=1; i<256; ++i) a2[i]=1ll*a2[i-1]*b%p;
b=1ll*b*a2[255]%p;
for(int i=1; i<256; ++i) a3[i]=1ll*a3[i-1]*b%p;
}
int qp(int x)
{return 1ll*a3[x>>24]*a2[(x>>16)&255]%p
*a1[(x>>8)&255]%p*a0[x&255]%p;}
}Z;
int x[1000003],y[1000003],z[1000003];
int tx[1000003],sy[1000003],ans[1000003];
vector<int> vx[1000003],qu[1000003];
int op[1000003],v[1000003],pre[1000003];
int pw[1000003];
signed main()
{
int n=read(),m=read();
pw[0]=1;
for(int i=1; i<=m; ++i) pw[i]=(pw[i-1]<<1)%q;
for(int i=1; i<=n; ++i)
x[i]=read(),y[i]=read(),z[i]=read(),
vx[x[i]].push_back(i);
for(int i=1; i<=m; ++i)
{
op[i]=read(),v[i]=read();
if(op[i]==2) qu[v[i]].push_back(i);
}
for(int i=1; i<=n; ++i)
if((int)vx[i].size()>=B)
{
for(int j=1; j<=m; ++j)
pre[j]=(pre[j-1]+(op[j]==1&&v[j]==i));
for(int j:vx[i])
{
Z.init(z[j]);
for(int k:qu[y[j]])
ans[k]=(ans[k]+Z.qp(pw[pre[k]]))%p;
}
}
else for(int j:vx[i])
sy[y[j]]=(sy[y[j]]+z[j])%p;
for(int i=1; i<=m; ++i)
if(op[i]==2) printf("%d\n",(ans[i]+sy[v[i]])%p);
else if(vx[v[i]].size()<B)
for(int j:vx[v[i]])
sy[y[j]]=(sy[y[j]]+p-z[j])%p,
z[j]=1ll*z[j]*z[j]%p,
sy[y[j]]=(sy[y[j]]+z[j])%p;
return 0;
}