单根做法找不到离散对数求条
查看原帖
单根做法找不到离散对数求条
530468
_determination_楼主2024/10/30 15:08

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;
}
2024/10/30 15:08
加载中...