QOJ.ac
QOJ
ID | Problem | Submitter | Result | Time | Memory | Language | File size | Submit time | Judge time |
---|---|---|---|---|---|---|---|---|---|
#222528 | #7608. Cliques | ucup-team1516# | WA | 2ms | 4488kb | C++14 | 6.7kb | 2023-10-21 17:31:07 | 2023-10-21 17:31:08 |
Judging History
answer
#include <string.h>
#include <algorithm>
#include <array>
#include <bitset>
#include <cassert>
#include <cfloat>
#include <climits>
#include <cmath>
#include <complex>
#include <ctime>
#include <deque>
#include <fstream>
#include <functional>
#include <iomanip>
#include <iostream>
#include <iterator>
#include <list>
#include <map>
#include <memory>
#include <queue>
#include <random>
#include <set>
#include <stack>
#include <string>
#include <unordered_map>
#include <unordered_set>
#include <utility>
#include <vector>
using namespace std;
constexpr int mod = 1000000007;
void mpl(int &x,int y) {
x += y;
if(x >= mod) x -= mod;
}
void mrg(pair<int,int>&a,pair<int,int>b) {
a.first = 1ll*a.first*b.first%mod;
a.second = (1ll*a.second*b.first+b.second)%mod;
}
int f[200200],cnt[200200];
template <typename T>
struct LazySegmentTree {
int n;
vector<T> dat;
vector<pair<int,int>>lazy;
LazySegmentTree() {};
LazySegmentTree(int N) {
n = 1;
while(n < N) {
n *= 2;
}
dat.resize(n*2,0);
lazy.resize(n*2,{1,0});
}
void eval(int k,int l,int r) {
if(lazy[k] == make_pair(1,0)) return;
if(k < n) {
mrg(lazy[k*2],lazy[k]);
mrg(lazy[k*2+1],lazy[k]);
}
dat[k] = (1ll*dat[k]*lazy[k].first+lazy[k].second)%mod;
lazy[k] = {1,0};
}
void update(int a, int b, pair<int,int> x, int k, int l, int r) {
eval(k,l,r);
if(a <= l && r <= b) {
mrg(lazy[k],x);
eval(k,l,r);
}
else if(a < r && l < b) {
update(a, b, x, k*2, l, (l+r)/2);
update(a, b, x, k*2+1, (l+r)/2, r);
dat[k] = (dat[k*2]+dat[k*2+1])%mod;
}
}
void update(int a, int b, pair<int,int> x) {//[a,b)
update(a, b, x, 1, 0, n);
}
T query_sub(int a, int b, int k, int l, int r) {
eval(k,l,r);
if (r <= a || b <= l) {
return 0;
}
else if (a <= l && r <= b) {
return dat[k];
}
else {
T vl = query_sub(a, b, k*2, l, (l+r)/2);
T vr = query_sub(a, b, k*2+1, (l+r)/2, r);
return (vl+vr)%mod;
}
}
T query(int a, int b) {//[a,b)
return query_sub(a, b, 1, 0, n);
}
};
struct HLD { // 根が 0 でない時に注意
vector<int>p,sz,in,nxt;
LazySegmentTree<int> bit;
void dfs1(vector<vector<int>>&c,int v = 0) {
sz[v] = 1;
for(int &w:c[v]) {
dfs1(c,w);
sz[v] += sz[w];
if(sz[w] > sz[c[v][0]]) {
swap(w,c[v][0]);
}
}
}
void dfs2(vector<vector<int>>&c,int &t,int v = 0) {
in[v] = t;
t++;
for(int w:c[v]) {
if(w == c[v][0]) {
nxt[w] = nxt[v];
}
else {
nxt[w] = w;
}
dfs2(c,t,w);
}
}
HLD(vector<int>A,vector<int>p,vector<vector<int>>c):p(p) {
int N = A.size();
sz.resize(N,0);
dfs1(c);
in.resize(N,0);
nxt.resize(N,0);
int t = 0;
dfs2(c,t);
vector<int>tmp(N);
for(int i = 0; i < N; i++) {
tmp[in[i]] = A[i];
}
LazySegmentTree<int>init(tmp.size());
for(int i = 0; i < tmp.size(); i++) {
init.update(i,i+1,{1,tmp[i]});
}
bit = init;
}
int lca(int u,int v) {
while(true) {
if(in[u] > in[v]) {
swap(u,v);
}
if(nxt[u] == nxt[v]) {
return u;
}
v = p[nxt[v]];
}
}
void update(int v,int x) {
bit.update(in[v],in[v]+1,{1,x});
}
void update2(int u,int v,int x) {
int w = lca(u,v);
int ans = 0;
while(nxt[u] != nxt[w]) {
bit.update(in[nxt[u]],in[u]+1,{x,0});
u = p[nxt[u]];
}
bit.update(in[w],in[u]+1,{x,0});
while(nxt[v] != nxt[w]) {
bit.update(in[nxt[v]],in[v]+1,{x,0});
v = p[nxt[v]];
}
bit.update(in[w]+1,in[v]+1,{x,0});
}
void update3(int u,int v,int x) {
int w = lca(u,v);
int ans = 0;
while(nxt[u] != nxt[w]) {
bit.update(in[nxt[u]],in[u]+1,{1,x});
u = p[nxt[u]];
}
bit.update(in[w],in[u]+1,{1,x});
while(nxt[v] != nxt[w]) {
bit.update(in[nxt[v]],in[v]+1,{1,x});
v = p[nxt[v]];
}
bit.update(in[w]+1,in[v]+1,{1,x});
}
long long query(int u,int v) {
int w = lca(u,v);
int ans = 0;
while(nxt[u] != nxt[w]) {
mpl(ans,bit.query(in[nxt[u]],in[u]+1));
u = p[nxt[u]];
}
mpl(ans,bit.query(in[w],in[u]+1));
while(nxt[v] != nxt[w]) {
mpl(ans,bit.query(in[nxt[v]],in[v]+1));
v = p[nxt[v]];
}
mpl(ans,bit.query(in[w]+1,in[v]+1));
return ans;
}
};
int main() {
ios::sync_with_stdio(false);
cin.tie(nullptr);
int n;
cin >> n;
vector<vector<int>>ki(n);
for(int i = 0; i < n-1; i++) {
int u,w;
cin >> u >> w;
u--;
w--;
ki[u].push_back(w);
ki[w].push_back(u);
}
vector<int>p(n,-1);
vector<vector<int>>c(n);
vector<int>a(n);
queue<int>que;
que.push(0);
while(!que.empty()) {
int x = que.front();
que.pop();
for(int i:ki[x]) {
if(p[i] == -1 && i != 0) {
que.push(i);
p[i] = x;
c[x].push_back(i);
}
}
}
f[0] = 1;
for(int i = 1; i <= 200000; i++) {
f[i] = 2ll*f[i-1]%mod;
}
HLD hld1(a,p,c);
HLD hld2(a,p,c);
int ans = 0;
int q;
cin >> q;
while(q--) {
char c;
int u,v;
cin >> c >> u >> v;
u--;
v--;
int lc = hld1.lca(u,v);
if(c == '+') {
mpl(ans,hld1.query(u,v));
hld1.update2(u,v,2);
int x = hld2.query(lc,lc)-cnt[lc];
mpl(ans,f[x]);
hld1.update(lc,f[x]);
hld2.update3(u,v,1);
cnt[lc]++;
}
else {
int x = hld2.query(lc,lc)-cnt[lc];
mpl(ans,mod-f[x]);
hld1.update(lc,mod-f[x]);
hld2.update3(u,v,-1);
cnt[lc]--;
mpl(ans,hld1.query(u,v));
hld1.update2(u,v,500000004);
}
cout << ans << endl;
}
}
Details
Tip: Click on the bar to expand more detailed information
Test #1:
score: 100
Accepted
time: 1ms
memory: 4488kb
input:
5 1 2 5 1 2 3 4 2 6 + 4 5 + 2 2 + 1 3 - 2 2 + 2 3 + 4 4
output:
1 3 7 3 7 9
result:
ok 6 lines
Test #2:
score: -100
Wrong Answer
time: 2ms
memory: 4464kb
input:
20 8 7 19 10 12 14 3 16 17 13 7 10 5 6 1 9 15 12 5 2 16 13 3 11 20 14 18 6 1 14 16 20 11 10 3 4 20 6 30 + 10 20 + 14 20 + 12 17 - 14 20 - 12 17 + 4 6 + 8 20 + 3 6 - 10 20 + 2 17 + 1 16 + 6 10 + 9 10 + 5 15 + 7 8 - 7 8 + 2 5 + 3 18 + 1 20 + 8 16 - 3 18 - 5 15 + 4 20 + 14 16 - 4 6 + 8 19 + 4 7 - 1 16 ...
output:
1 3 7 12 13 15 19 27 40 48 64 96 160 288 290 288 292 548 1060 1316 2548 3040 3424 4192 5680 5696 5776 6541 6797 7485
result:
wrong answer 4th lines differ - expected: '3', found: '12'