結果
| 問題 |
No.2265 Xor Range Substring Sum Query
|
| コンテスト | |
| ユーザー |
nonon
|
| 提出日時 | 2024-04-08 18:20:04 |
| 言語 | C++17 (gcc 13.3.0 + boost 1.87.0) |
| 結果 |
AC
|
| 実行時間 | 789 ms / 5,000 ms |
| コード長 | 2,304 bytes |
| コンパイル時間 | 2,529 ms |
| コンパイル使用メモリ | 201,680 KB |
| 最終ジャッジ日時 | 2025-02-20 23:12:20 |
|
ジャッジサーバーID (参考情報) |
judge2 / judge4 |
(要ログイン)
| ファイルパターン | 結果 |
|---|---|
| sample | AC * 2 |
| other | AC * 22 |
ソースコード
#include<bits/stdc++.h>
#include<atcoder/modint>
using namespace std;
using mint=atcoder::modint998244353;
template<typename S, auto op, auto e>
struct xor_segtree
{
xor_segtree():xor_segtree(0){}
xor_segtree(int n_):xor_segtree(vector<S>(n_,e())){}
xor_segtree(const vector<S>&v):n((int)v.size())
{
log=0;
while((1<<log)<n)log++;
mid=(log+1)/2;
sz=1<<log;
node.assign((log+1)*sz,e());
for(int i=0;i<n;i++)node[i]=v[i];
for(int i=0;i<log;i++)for(int j=0;j<n;j++)update(i,j);
}
void set(int p, S x)
{
assert(0<=p&&p<n);
node[p]=x;
for(int i=0;i<mid;i++)for(int j=0;j<(1<<(i+1));j++)update(i,p^j);
}
S get(int p)
{
assert(0<=p&&p<n);
return node[p];
}
S prod(int l, int r, int x)
{
assert(0<=l&&l<=r&&r<=n);
assert(0<=x&&x<sz);
S pl=e(),pr=e();
int d=0;
while(l<r&&d<mid)
{
if(l&1)pl=op(pl,node[idx(d,((l++)<<d)^x)]);
if(r&1)pr=op(node[idx(d,((--r)<<d)^x)],pr);
l>>=1,r>>=1,d++;
}
while(l<r)pl=op(pl,node[idx(mid,((l++)<<mid)^x)]);
return op(pl,pr);
}
private:
int n,log,mid,sz;
vector<S>node;
int idx(int p, int q){return p*sz+q;}
void update(int p, int q){node[idx(p+1,q)]=op(node[idx(p,q)],node[idx(p,q^(1<<p))]);}
};
mint p2[1<<18],p11[1<<18];
pair<mint,int>op(pair<mint,int>a, pair<mint,int>b)
{
auto[xa,sa]=a;
auto[xb,sb]=b;
return make_pair(xa*p11[sb]+xb*p2[sa],sa+sb);
}
pair<mint,int>e(){return make_pair(0,0);}
int main()
{
ios::sync_with_stdio(false);
cin.tie(nullptr);
int N;
string S;
cin>>N>>S;
N=1<<N;
p2[0]=p11[0]=1;
for(int i=1;i<N;i++)
{
p2[i]=2*p2[i-1];
p11[i]=11*p11[i-1];
}
vector<pair<mint,int>>A(N);
for(int i=0;i<N;i++)A[i]=make_pair(S[i]-'0',1);
xor_segtree<pair<mint,int>,op,e>seg(A);
int Q;
cin>>Q;
while(Q--)
{
int t;
cin>>t;
if(t==1)
{
int p,x;
cin>>p>>x;
seg.set(p,make_pair(x,1));
}
else
{
int l,r,x;
cin>>l>>r>>x;
cout<<seg.prod(l,r+1,x).first.val()<<'\n';
}
}
}
nonon