結果
問題 | No.1502 Many Simple Additions |
ユーザー |
![]() |
提出日時 | 2022-12-04 08:49:54 |
言語 | C++17 (gcc 13.3.0 + boost 1.87.0) |
結果 |
WA
|
実行時間 | - |
コード長 | 3,264 bytes |
コンパイル時間 | 2,336 ms |
コンパイル使用メモリ | 209,360 KB |
最終ジャッジ日時 | 2025-02-09 04:54:47 |
ジャッジサーバーID (参考情報) |
judge4 / judge3 |
(要ログイン)
ファイルパターン | 結果 |
---|---|
sample | AC * 5 |
other | AC * 32 WA * 7 |
ソースコード
#include <bits/stdc++.h>using namespace std;#define REP(i,n) for(int i=0;i<(n);i++)#include <atcoder/modint>using namespace atcoder;using mint=modint1000000007;ostream& operator<<(ostream &os,mint a){os<<a.val();return os;}istream& operator>>(istream &is,mint &a){long long b;is>>b;a=b;return is;}class IntegerSumRuleUnionFind{using ll=long long;int n,num;vector<int> sz,parent;vector<pair<int,ll>> potential;vector<optional<ll>> value;public:IntegerSumRuleUnionFind()=default;IntegerSumRuleUnionFind(int n):n(n),num(n),sz(n,1),parent(n,0),potential(n,{1,0}),value(n,nullopt){iota(parent.begin(),parent.end(),0);}tuple<int,int,ll> from_root(int x){if(x==parent[x])return {x,1,0LL};auto [r,a,b]=from_root(parent[x]);auto [c,d]=potential[x];parent[x]=r;potential[x]={a*c,b*c+d};return {r,a*c,b*c+d};}int leader(int x){ return get<0>(from_root(x)); }bool same(int x,int y){assert(0<=x and x<n and 0<=y and y<n);return leader(x)==leader(y);}bool merge(int x,int y,ll sum){// 矛盾する場合は変更はせず false を返すassert(0<=x and x<n and 0<=y and y<n);auto [rx,a,b]=from_root(x);auto [ry,c,d]=from_root(y);if(rx==ry){if(a==c and b==d)return true;// ar+b + cr+d = sumif(a==-c)return b+d==sum;if((sum-b-d)&1)return false;ll r=(sum-b-d)/(a+c);if(value[rx] and value[rx].value()!=r)return false; // これ起きる?value[rx]=r;return true;}if(sz[rx]<sz[ry]){swap(rx,ry);swap(a,c);swap(b,d);}// a * rx + b + c * ry + d == sum// ry = -a/c rx + (sum-b-d)/csz[rx]+=sz[ry];parent[ry]=rx;potential[ry]={-a*c,(sum-b-d)*c};num--;return true;}optional<ll> val(int x){ return value[x]; }// x と y が隣接してないなら nullopt// x と y が隣接しているが、sum が一意でない場合も nulloptoptional<ll> sum(int x,int y){auto [rx,a,b]=from_root(x);auto [ry,c,d]=from_root(y);if(rx!=ry)return nullopt;if(a==c){assert(b==d);return nullopt;}return b+d;}int size(const int x){assert(0<=x and x<n);return sz[leader(x)];}int count()const{return num;}};using ll=long long;void chmin(ll&a,ll b){ a=min(a,b); }void chmax(ll&a,ll b){ a=max(a,b); }int main(){ios::sync_with_stdio(false);cin.tie(nullptr);int n,m,k;cin>>n>>m>>k;IntegerSumRuleUnionFind UF(n);REP(_,m){int x,y,z;cin>>x>>y>>z;x--;y--;if(!UF.merge(x,y,z)){cerr<<0<<endl;return 0;}}auto solve=[&](int upper){mint res=1;vector<ll> low(n,1),high(n,upper);REP(i,n){auto [r,a,b]=UF.from_root(i);if(UF.val(r)){ll v=UF.val(r).value()*a+b;if(v<0||upper<v)res=0;continue;}// 1 <= ra+b <= upperif(a==1){chmax(low[r],1-b);chmin(high[r],upper-b);}else{chmax(low[r],b-upper);chmin(high[r],b-1);}}REP(r,n)if(UF.leader(r)==r and !UF.val(r))res*=max(high[r]-low[r]+1,0LL);return res;};cout<< solve(k)-solve(k-1) <<endl;}