結果

問題 No.2295 Union Path Query (Medium)
ユーザー 沙耶花
提出日時 2023-05-05 22:53:18
言語 C++17
(gcc 13.3.0 + boost 1.87.0)
結果
AC  
実行時間 3,103 ms / 4,000 ms
コード長 4,291 bytes
コンパイル時間 4,729 ms
コンパイル使用メモリ 263,528 KB
最終ジャッジ日時 2025-02-12 19:13:45
ジャッジサーバーID
(参考情報)
judge5 / judge1
このコードへのチャレンジ
(要ログイン)
ファイルパターン 結果
sample AC * 3
other AC * 53
権限があれば一括ダウンロードができます
コンパイルメッセージ
main.cpp: In function ‘int main()’:
main.cpp:164:22: warning: ignoring return value of ‘int scanf(const char*, ...)’ declared with attribute ‘warn_unused_result’ [-Wunused-result]
  164 |                 scanf("%d",&t[i]);
      |                 ~~~~~^~~~~~~~~~~~
main.cpp:167:30: warning: ignoring return value of ‘int scanf(const char*, ...)’ declared with attribute ‘warn_unused_result’ [-Wunused-result]
  167 |                         scanf("%d %d",&a[i],&b[i]);
      |                         ~~~~~^~~~~~~~~~~~~~~~~~~~~
main.cpp:172:30: warning: ignoring return value of ‘int scanf(const char*, ...)’ declared with attribute ‘warn_unused_result’ [-Wunused-result]
  172 |                         scanf("%d %d",&a[i],&b[i]);
      |                         ~~~~~^~~~~~~~~~~~~~~~~~~~~
main.cpp:187:30: warning: ignoring return value of ‘int scanf(const char*, ...)’ declared with attribute ‘warn_unused_result’ [-Wunused-result]
  187 |                         scanf("%d",&a[i]);
      |                         ~~~~~^~~~~~~~~~~~
main.cpp:190:30: warning: ignoring return value of ‘int scanf(const char*, ...)’ declared with attribute ‘warn_unused_result’ [-Wunused-result]
  190 |                         scanf("%d",&a[i]);
      |                         ~~~~~^~~~~~~~~~~~

ソースコード

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

#include <stdio.h>
#include <bits/stdc++.h>
#include <atcoder/all>
using namespace atcoder;
using mint = modint998244353;
using namespace std;
#define rep(i,n) for (int i = 0; i < (n); ++i)
#define Inf32 1000000001
#define Inf64 4000000000000000001
template <typename T>
struct perArray{
struct node{
T value;
int l=-1,r=-1;
};
int sz;
vector<node> nodes;
vector<int> roots;
void build(vector<T> v,int now = -1){
if(now==-1){
sz = v.size();
nodes.push_back(node());
now = 0;
roots.push_back(0);
}
if(v.size()==1){
nodes[now].value = v[0];
return;
}
vector<T> l,r;
rep(i,v.size()){
if(i<v.size()/2){
l.push_back(v[i]);
}
else{
r.push_back(v[i]);
}
}
nodes[now].l = nodes.size();
nodes.push_back(node());
build(l,nodes[now].l);
nodes[now].r = nodes.size();
nodes.push_back(node());
build(r,nodes[now].r);
}
int set(int p, int ind, T x, int now = -1, int length = -1){
int ret = roots.size();
if(now==-1){
roots.push_back(nodes.size());
now = nodes.size();
nodes.push_back(nodes[roots[p]]);
length = sz;
}
if(length==1){
nodes[now].value = x;
}
else{
if(ind < (length>>1)){
int temp = nodes[now].l;
nodes[now].l = nodes.size();
nodes.push_back(nodes[temp]);
set(p,ind,x,nodes.size()-1,(length>>1));
}
else{
int temp = nodes[now].r;
nodes[now].r = nodes.size();
nodes.push_back(nodes[temp]);
set(p,ind - (length>>1),x,nodes.size()-1,(length+1)>>1);
}
}
return ret;
}
T get(int p,int ind,int now = -1,int length = -1){
if(now==-1){
now = roots[p];
length = sz;
}
if(length==1)return nodes[now].value;
if(ind<(length>>1)){
return get(p,ind,nodes[now].l,length>>1);
}
else{
return get(p,ind - (length>>1),nodes[now].r,(length+1)>>1);
}
}
int size(){
return sz;
}
};
struct perDsu{
perArray<int> A;
vector<int> roots;
perDsu(int n){
vector<int> t(n,-1);
A.build(t);
roots.push_back(0);
}
int merge(int p,int a,int b){
int ret = roots.size();
int La = leader(p,a);
int Lb = leader(p,b);
if(La==Lb)return p;
if(size(p,La)<size(p,Lb))swap(La,Lb);
int temp = A.set(roots[p],La,-(size(p,La)+size(p,Lb)));
roots.push_back(A.set(temp,Lb,La));
return ret;
}
bool same(int p,int a,int b){
return (leader(p,a)==leader(p,b));
}
int size(int p,int a){
int temp = A.get(roots[p],a);
if(temp<0)return -temp;
return size(p,temp);
}
int leader(int p,int a){
int temp = A.get(roots[p],a);
if(temp<0)return a;
return leader(p,temp);
}
vector<vector<int>> groups(int p){
vector<vector<int>> temp(A.size(),vector<int>());
rep(i,A.size()){
temp[leader(p,i)].push_back(i);
}
vector<vector<int>> ret;
rep(i,temp.size()){
if(temp[i].size()>0)ret.push_back(temp[i]);
}
return ret;
}
};
int main(){
int n,x0,q;
cin>>n>>x0>>q;
perDsu D(n);
vector<int> t(q+1),a(q+1),b(q+1),p(q+1);
int x= x0;
vector<int> memo(q+1);
for(int i=1;i<=q;i++){
scanf("%d",&t[i]);
p[i] = p[i-1];
if(t[i]==1){
scanf("%d %d",&a[i],&b[i]);
//cin>>a[i]>>b[i];
p[i] = D.merge(p[i],a[i],x);
}
if(t[i]==2){
scanf("%d %d",&a[i],&b[i]);
if(a[i]==b[i])continue;
if(D.same(p[i],a[i],b[i])){
int ok = 0,ng = i;
while(ng-ok>1){
int mid = (ok+ng)/2;
if(D.same(p[mid],a[i],b[i]))ng = mid;
else ok = mid;
}
memo[i] = b[ok+1];
x += b[ok+1];
x %= n;
}
}
if(t[i]==3){
scanf("%d",&a[i]);
}
if(t[i]==4){
scanf("%d",&a[i]);
x += a[i];
x %= n;
}
}
//cout<<'a'<<endl;
x = x0;
dsu D2(n);
vector<mint> A(n);
for(int i=1;i<=q;i++){
if(t[i]==1){
int la = D2.leader(a[i]),lb = D2.leader(x);
if(D2.same(la,lb))continue;
mint tt = D2.size(a[i]);
tt *= D2.size(x);
tt *= b[i];
tt += A[la] + A[lb];
D2.merge(la,lb);
int lc = D2.leader(la);
int ld = lc^la^lb;
A[ld] = 0;
A[lc] = tt;
}
if(t[i]==2){
if(a[i]==b[i]){
printf("0\n");
continue;
}
if(D.same(p[i],a[i],b[i])){
x += memo[i];
x %= n;
printf("%d\n",memo[i]);
//cout<<b[ok+1]<<endl;
}
else printf("-1\n");
}
if(t[i]==3){
printf("%d\n",A[D2.leader(a[i])].val());
}
if(t[i]==4){
x += a[i];
x %= n;
}
}
return 0;
}
הההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההה
XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX
0