rt。使用 bsgs 求离散对数,板子是从模板题贺下来的,感觉没什么问题,但是 assert 哪里会报错。
#include<bits/stdc++.h>
// #define int long long
#define endl '\n'
using namespace std;
const int mod=1e9+7,inf=0x3f3f3f3f3f3f3f3f;
const int N=1e6+10,M=2e5+10;
int n,q;
int x[N],y[N],w[N];
vector<int>xx[N],yy[N];
const int B=4000,lim=30000;
int tag[N],val[N],cnt[N];
void add(int &x,int y){x=(1ll*x+y+mod)%mod;}
int lg[N];
//bsgs begin
unordered_map<int,int>mp;
const int t=40000;
int bsgs(int a,int b)
{
mp.clear();
int k=1;
for ( int i = 1 ; i <= t ; i++ )
{
k=k*a%mod;
mp[k*b%mod]=i;
}
int k2=1;
for ( int i = 0 ; i <= mod/t ; i++ )
{
k2=k2*k%mod;
if(mp[k2]||k2==b)
{
int j=mp[k2];
return (((i+1)*t-j)%mod+mod)%mod;
}
}
return -1;
}
//bsgs end
int getlg(int x)
{
int ans=bsgs(5,x);
assert(ans!=-1);
return ans;
}
int pw1[N],pw2[N];
void init()
{
pw1[0]=1;
for ( int i = 1 ; i <= lim ; i++ )pw1[i]=pw1[i-1]*5%mod;
pw2[0]=1;
for ( int i = 1 ; i <= mod/lim ; i++ )pw2[i]=pw2[i-1]*pw1[lim]%mod;
}
int fp(int p)
{
p%=(mod-1);
return pw2[p/lim]*pw1[p%lim]%mod;
}
signed main()
{
ios::sync_with_stdio(false);
cin.tie(0),cout.tie(0);
cin >> n >> q;
for ( int i = 1 ; i <= n ; i++ )
{
cin >> x[i] >> y[i] >> w[i];
lg[i]=getlg(w[i]);
cnt[x[i]]++;
}
init();
for ( int i = 1 ; i <= n ; i++ )
if(cnt[x[i]]<B)xx[x[i]].push_back(i),add(val[y[i]],w[i]);
else yy[y[i]].push_back(i);
for ( int i = 1 ; i <= n ; i++ )tag[i]=1;
while(q--)
{
int op,v;
cin >> op >> v;
if(op==1)
{
if(cnt[v]>=B)tag[v]=tag[v]*2%(mod-1);
else for ( auto i:xx[v] ){
add(val[y[i]],-w[i]);
w[i]=1ll*w[i]*w[i]%mod;
add(val[y[i]],w[i]);
}
}else{
long long ans=val[v];
for ( auto i:yy[v] )ans+=fp(tag[x[i]]*lg[i]);
cout << ans%mod << endl;
}
}
return 0;
}