結果

問題 No.1502 Many Simple Additions
ユーザー cureskol
提出日時 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
権限があれば一括ダウンロードができます

ソースコード

diff #
プレゼンテーションモードにする

#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 = sum
if(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)/c
sz[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 nullopt
optional<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 <= upper
if(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;
}
הההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההה
XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX
0