2023 rcpc

This commit is contained in:
2024-04-22 16:45:09 +03:00
parent a0ddb657b7
commit 156202ada0
61 changed files with 4462 additions and 0 deletions

View File

@@ -0,0 +1,66 @@
#include <iostream>
#include <vector>
#include <algorithm>
#include <cassert>
#warning That's the baby, that's not my baby
typedef long long ll;
void solve() {
int n;
std::cin >> n;
int a[n];
for (int i = 0; i < n; i++) {
std::cin >> a[i];
}
int b[n];
for (int i = 0; i < n; i++) {
std::cin >> b[i];
}
/// e clar ca cel putin una dintre subsecvente se termina pe pozitia n (proof by the proof is left as an excersise for the reader)
int answer = 0;
// 1. prima subsecventa se termina pe pozitia n
for (int r2 = n - 1; r2 >= 0; r2--) {
int cur = 0;
for (int l2 = r2; l2 >= 0; l2--) {
if (a[n - (r2 - l2 + 1)] != b[l2]) {
cur++;
}
answer = std::max(answer, cur);
}
}
// 2. a doua subsecventa se termina pe pozitia n
for (int r1 = n - 1; r1 >= 0; r1--) {
int cur = 0;
for (int l1 = r1; l1 >= 0; l1--) {
if (a[l1] != b[n - (r1 - l1 + 1)]) {
cur++;
}
answer = std::max(answer, cur);
}
}
std::cout << answer;
}
int main() {
std::ios_base::sync_with_stdio(false);
std::cin.tie(0);
int t;
std::cin >> t;
while (t--) {
solve();
std::cout << '\n';
}
return 0;
}

View File

@@ -0,0 +1,45 @@
#include <bits/stdc++.h>
using namespace std;
int n,a[10005],b[10005];
void testcase()
{
cin >> n;
for (int i = 1; i <= n; i++)
cin >> a[i];
for (int i = 1; i <= n; i++)
cin >> b[i];
int ans = 0;
for (int i = n; i >= 1; i--)
{
int cur = 0;
for (int j = i; j >= 1; j--)
{
if (b[j] != a[n - (i - j)])
cur++;
}
ans = max(ans,cur);
}
for (int i = n; i >= 1; i--)
{
int cur = 0;
for (int j = i; j >= 1; j--)
{
if (a[j] != b[n - (i - j)])
cur++;
}
ans = max(ans,cur);
}
cout << ans << '\n';
}
int main()
{
int tc;
cin >> tc;
while (tc--)
testcase();
return 0;
}

View File

@@ -0,0 +1,161 @@
#include <bits/stdc++.h>
#warning That's the baby, that's not my baby
typedef long long ll;
using namespace std;
/**
Solutie:
Rotim la 45, acum ne fixam unul dintre cele K puncte.
Observam ca va face cel mult n + m - 1 (< 2 * max(n, m)) pasi =>
ne vom uita pentru r pasi, care este intaltimea maxima la care putem ajunge.
Practic avem un query de maxim pe un patrat din matrice => putem face rmq
Complexitate temporala: O(N^2 * logN + K * N)
**/
const int NMAX = 750;
int a[NMAX + 1][NMAX + 1];
int b[2 * NMAX + 2][2 * NMAX + 2];
int rmqLine[12][2 * NMAX + 1][2 * NMAX + 1];
int rmqCol[12][2 * NMAX + 1][2 * NMAX + 1];
int lg2[2 * NMAX + 1];
int N;
const int p2[14] = {1, 2, 4, 8, 16, 32, 64, 128, 256, 512, 1024, 2048, 4096, 8192};
int queryLine (int x, int l, int r) {
l = max(l, 1);
r = min(r, N);
int k = lg2[r - l + 1];
return max(rmqLine[k][x][l], rmqLine[k][x][r - p2[k] + 1]);
}
int queryCol (int x, int l, int r) {
l = max(l, 1);
r = min(r, N);
int k = lg2[r - l + 1];
return max(rmqCol[k][x][l], rmqCol[k][x][r - p2[k] + 1]);
}
int answer[NMAX * NMAX + 1];
int mini[2 * NMAX + 1];
int main() {
ios_base::sync_with_stdio(false);
cin.tie(0);
int n, m, k;
cin >> n >> m >> k;
N = max(n, m);
int maxel = 0;
for (int i = 1; i <= n; i++) {
for (int j = 1; j <= m; j++) {
cin >> a[i][j];
b[i + j - 1][i - j + N] = a[i][j];
maxel = std::max(maxel, a[i][j]);
}
}
N <<= 1;
for (int i = 2; i <= N; i++) {
lg2[i] = lg2[i >> 1] + 1;
}
for (int i = 1; i <= N; i++) {
for (int j = 1; j <= N; j++) {
if (!b[i][j]) {
rmqLine[0][i][j] = rmqCol[0][j][i] = 1e9;
}
rmqLine[0][i][j] = rmqCol[0][j][i] = b[i][j];
// cout << setw(3) << b[i][j];
}
// cout << '\n';
}
for (int k = 1; p2[k] <= N; k++) {
for (int i = 1; i <= N; i++) {
for (int j = 1; j + p2[k] - 1 <= N; j++) {
rmqLine[k][i][j] = max(rmqLine[k - 1][i][j], rmqLine[k - 1][i][j + p2[k - 1]]);
}
}
for (int j = 1; j <= N; j++) {
for (int i = 1; i + p2[k] - 1 <= N; i++) {
rmqCol[k][j][i] = max(rmqCol[k - 1][j][i], rmqCol[k - 1][j][i + p2[k - 1]]);
}
}
}
for (int r = 1; r <= N; r++) {
mini[r] = 1e9;
}
while (k--) {
int x, y;
cin >> x >> y;
int i = x + y - 1;
int j = x - y + N / 2;
// cout << " ? " << b[i][j] << " - " << a[x][y] << '\n';
int cur = 0;
for (int r = 1; r <= N; r++) {
int x1 = i - r + 1, y1 = j - r + 1, x2 = i + r - 1, y2 = j + r - 1;
if (x1 > 0) {
cur = max(cur, queryLine(x1, y1, y2));
}
if (x2 <= N) {
cur = max(cur, queryLine(x2, y1, y2));
}
if (y1 > 0) {
cur = max(cur, queryCol(y1, x1, x2));
}
if (y2 <= N) {
cur = max(cur, queryCol(y2, x1, x2));
}
mini[r] = min(mini[r], cur);
}
}
for (int r = 1; r <= N; r++) {
// cout << " > " << mini[r] << '\n';
if (mini[r] <= n * m) {
answer[mini[r] + 1] = max(answer[mini[r] + 1], r);
}
}
for (int i = 1; i <= n * m; i++) {
answer[i] = max(answer[i], answer[i - 1]);
if (i > maxel) {
std::cout << "-1 ";
} else {
cout << answer[i] << ' ';
}
}
return 0;
}
/**
6 5 6
30 14 11 22 16
7 5 6 3 23
20 1 5 2 17
21 1 4 2 6
17 7 3 24 3
26 25 13 14 10
2 2
3 2
4 4
5 5
2 4
4 3
**/

View File

@@ -0,0 +1,123 @@
#include <bits/stdc++.h>
#pragma GCC optimize("O3")
using namespace std;
int aint[2][1402][5602];
int rmq[2][1402][14][1402];
int logs[1402];
vector<vector<int> > rot(2000, vector<int> (2000));
void build(int LC, int poz, int nod, int L, int R)
{
for(int i = 1; i <= 1400; i++)
{
if(LC == 0)
rmq[LC][poz][0][i] = rot[poz][i];
else
rmq[LC][poz][0][i] = rot[i][poz];
//if(LC == 1 && poz == 703 && i >= 0 && i <= 15)
//cout << rot[i][poz] << " ";
}
//if(LC == 1 && poz == 703)
// cout << '\n';
for(int i = 1; i <= logs[1400]; i++)
{
for(int j = 1; j + (1<<i) - 1 <= 1400; j++)
{
rmq[LC][poz][i][j] = max(rmq[LC][poz][i-1][j], rmq[LC][poz][i-1][j+(1<<(i-1))]);
//if(LC == 1 && poz == 703 && j <= 15)
// cout << rmq[LC][poz][i][j] << " ";
}
//if(LC == 1 && poz == 703)
// cout << '\n';
}
}
int query(int LC, int poz, int nod, int st, int dr, int L, int R)
{
int lg = logs[R-L+1];
return max(rmq[LC][poz][lg][L], rmq[LC][poz][lg][R-(1<<lg)+1]);
}
int minimaxi[1402], ans[500002];
int main()
{
ios_base::sync_with_stdio(false);
cin.tie(NULL);
int n, m, k;
cin >> n >> m >> k;
vector<vector<int> > v(n+1, vector<int> (m+1));
for(int i = 1; i <= n; i++)
for(int j = 1; j <= m; j++)
cin >> v[i][j];
for(int i = 1; i <= n*m; i++)
ans[i] = -1;
for(int i = 2; i <= 1400; i++)
logs[i] = logs[i/2] + 1;
for(int i = 1; i <= n; i++)
for(int j = 1; j <= m; j++)
rot[i+j][i-j+700] = v[i][j];
for(int i = 1; i <= n+m; i++)
build(0, i, 1, 1, 1400);
for(int i = 1; i < 1400; i++)
build(1, i, 1, 1, 1400);
for(int i = 0; i <= 1400; i++)
minimaxi[i] = 1000000;
for(int i = 1; i <= k; i++)
{
int L, C;
cin >> L >> C;
int line = L+C;
int column = L-C+700;
int mxx = 0;
for(int dist = 0; dist <= n+m; dist++)
{
bool ok = 0;
// going up
int first_line = max(1, line-dist);
int last_line = min(1400, line+dist);
int first_column = max(1, column-dist);
int last_column = min(1400, column+dist);
//if(i == 3)
// cout << i << " " << line << " " << column << " " << first_line << " " << last_line << " " << first_column << " " << last_column << '\n';
if(first_line)
ok = 1, mxx = max(mxx, query(0, first_line, 1, 1, 1400, first_column, last_column));
if(last_line <= 1400)
ok = 1, mxx = max(mxx, query(0, last_line, 1, 1, 1400, first_column, last_column));
if(first_column)
ok = 1, mxx = max(mxx, query(1, first_column, 1, 1, 1400, first_line, last_line));
//if(i == 3)
// cout << query(1, last_column, 1, 1, 1400, first_line, last_line) << '\n';
if(last_column < 1400)
ok = 1, mxx = max(mxx, query(1, last_column, 1, 1, 1400, first_line, last_line));
minimaxi[dist] = min(minimaxi[dist], mxx);
//if(i == 3 && mxx == 48)
// cout << "CN " << line << " " << column << " " << dist << '\n';
if(ok == 0)
break;
}
}
int lst = 0;
for(int i = 0; i <= 1400; i++)
{
if(minimaxi[i] <= n*m)
for(int j = lst+1; j <= min(n*m, minimaxi[i]); j++)
ans[j] = i;
lst = minimaxi[i];
}
for(int i = 1; i <= n*m; i++)
cout << ans[i] << " ";
return 0;
}

View File

@@ -0,0 +1,311 @@
#include <bits/stdc++.h>
#include <ext/pb_ds/assoc_container.hpp> // Common file
#include <ext/pb_ds/tree_policy.hpp> // Including tree_order_statistics_node_update
#define MIN(a, b) (((a) < (b)) ? (a) : (b))
#define MAX(a, b) (((a) < (b)) ? (b) : (a))
#pragma GCC optimize("Ofast")
#pragma GCC optimize("fast-math")
#pragma GCC optimize("unroll-loops")
#pragma GCC target("avx2")
using namespace std;
using namespace __gnu_pbds;
mt19937_64 rng(chrono::steady_clock().now().time_since_epoch().count());
typedef tree<
int,
null_type,
less<int>,
rb_tree_tag,
tree_order_statistics_node_update>
ordered_set;
struct custom_hash {
static uint64_t splitmix64(uint64_t x) {
// http://xorshift.di.unimi.it/splitmix64.c
x += 0x9e3779b97f4a7c15;
x = (x ^ (x >> 30)) * 0xbf58476d1ce4e5b9;
x = (x ^ (x >> 27)) * 0x94d049bb133111eb;
return x ^ (x >> 31);
}
size_t operator()(uint64_t x) const {
static const uint64_t FIXED_RANDOM = chrono::steady_clock::now().time_since_epoch().count();
return splitmix64(x + FIXED_RANDOM);
}
};
typedef long long ll;
typedef unsigned long long ull;
typedef long double ld;
typedef pair<ll,ll> pll;
typedef pair<int,int> pii;
int n,m,k,a[755][755];
int rmq_st[14][2*755][2*755],rmq_dr[14][2*755][2*755],nmat[2*755][2*755],loga[200005];
pair<int, int> st[2*755][2*755], dr[2*755][2*755];
int mini[200005],sol[755*755];
bool inside(int lin, int col)
{
return (lin>=1 && lin<=n && col>=1 && col<=m);
}
void la_dreapta()
{
int cnt=0, i, j, k,lin,col;
for(i=1; i<=n; i++)
{
++cnt; nmat[cnt][0]=0;
lin=i; col=1;
while(inside(lin, col))
{
nmat[cnt][++nmat[cnt][0]]=a[lin][col];
dr[lin][col]={cnt, nmat[cnt][0]};
col++; lin--;
}
}
for(i=2; i<=m; i++)
{
++cnt; nmat[cnt][0]=0;
lin=n; col=i;
while(inside(lin, col))
{
nmat[cnt][++nmat[cnt][0]]=a[lin][col];
dr[lin][col]={cnt, nmat[cnt][0]};
lin--; col++;
}
}
for(i=1; i<=cnt; i++)
{
for(j=nmat[i][0]; j>=1; j--)
{
rmq_dr[0][i][j]=nmat[i][j];
for(k=1; k<=12; k++)
{
rmq_dr[k][i][j]=rmq_dr[k-1][i][j];
int poz=j+(1<<(k-1));
if(poz<=nmat[i][0])
rmq_dr[k][i][j]=max(rmq_dr[k][i][j], rmq_dr[k-1][i][poz]);
}
}
}
}
void la_stanga()
{
int cnt=0, i, j, k, lin, col;
for(i=1; i<=n; i++)
{
++cnt; nmat[cnt][0]=0;
lin=i; col=m;
while(inside(lin, col))
{
nmat[cnt][++nmat[cnt][0]]=a[lin][col];
st[lin][col]={cnt, nmat[cnt][0]};
col--; lin--;
}
}
for(i=m-1; i>=1; i--)
{
++cnt; nmat[cnt][0]=0;
lin=n; col=i;
while(inside(lin, col))
{
nmat[cnt][++nmat[cnt][0]]=a[lin][col];
st[lin][col]={cnt, nmat[cnt][0]};
lin--; col--;
}
}
for(i=1; i<=cnt; i++)
{
for(j=nmat[i][0]; j>=1; j--)
{
rmq_st[0][i][j]=nmat[i][j];
for(k=1; k<=12; k++)
{
rmq_st[k][i][j]=rmq_st[k-1][i][j];
int poz=j+(1<<(k-1));
if(poz<=nmat[i][0])
rmq_st[k][i][j]=max(rmq_st[k][i][j], rmq_st[k-1][i][poz]);
}
}
}
}
int rmq_query_dr(int lin, int st, int dr)
{
ll lg=loga[dr-st+1];
return max(rmq_dr[lg][lin][st], rmq_dr[lg][lin][dr-(1<<lg)+1]);
}
int rmq_query_st(int lin, int st, int dr)
{
ll lg=loga[dr-st+1];
return max(rmq_st[lg][lin][st], rmq_st[lg][lin][dr-(1<<lg)+1]);
}
int query_st(int l1, int c1, int l2, int c2)
{
pair<int, int> p1=st[l1][c1], p2=st[l2][c2];
if(p1.first!=p2.first) return -1;
return rmq_query_st(p1.first, p1.second, p2.second);
}
int query_dr(int l1, int c1, int l2, int c2)
{
pair<int, int> p1=dr[l1][c1], p2=dr[l2][c2];
if(p1.first!=p2.first) return -1;
return rmq_query_dr(p1.first, p1.second, p2.second);
}
int main()
{
ios_base::sync_with_stdio(false);
cin.tie(0);
cout.tie(0);
mini[0]=1e9;
for(int i=1;i<=2e5;i++)
{
mini[i]=1e9;
for(int bit=0;bit<=20;bit++)
if((1<<bit)<=i)
loga[i]=bit;
}
cin>>n>>m>>k;
cin.get();
for(int i=1;i<=n;i++)
{
string s;
getline(cin,s);
int nr=0;
int j=1;
for(char c:s)
{
if(isdigit(c))
nr=nr*10+c-'0';
else
{
a[i][j]=nr;
j++;
nr=0;
}
}
a[i][j]=nr;
}
for(int i=1;i<=n*m;i++)
sol[i]=-1;
la_dreapta();
la_stanga();
int ind=0;
while(k--)
{
ind++;
int x,y;
cin>>x>>y;
vector<int> v;
int maxim=a[x][y];
v.push_back(maxim);
for(int L=1;L<=n+m;L++)
{
int i2=x-L;
int j2=y;
int i1=x;
int j1=y-L;
if(i2<=0)
{
int add=1-i2;
add=abs(add);
i2+=add;
j2-=add;
}
if(j1<=0)
{
int add=1-j1;
add=abs(add);
j1+=add;
i1-=add;
}
if(i1>=i2&&j1<=j2&&inside(i1,j1)&&inside(i2,j2))
maxim=max(maxim,query_dr(i1,j1,i2,j2));
i1=x;
j1=y+L;
if(j1>m)
{
int add=j1-m;
add=abs(add);
j1-=add;
i1-=add;
}
i2=x-L;
j2=y;
if(i2<=0)
{
int add=1-i2;
add=abs(add);
i2+=add;
j2+=add;
}
if(i1>=i2&&j1>=j2&&inside(i1,j1)&&inside(i2,j2))
maxim=max(maxim,query_st(i1,j1,i2,j2));
i1=x+L;
j1=y;
i2=x;
j2=y+L;
if(i1>n)
{
int add=i1-n;
add=abs(add);
i1-=add;
j1+=add;
}
if(j2>m)
{
int add=j2-m;
add=abs(add);
j2-=add;
i2+=add;
}
if(i1>=i2&&j1<=j2&&inside(i1,j1)&&inside(i2,j2))
maxim=max(maxim,query_dr(i1,j1,i2,j2));
i2=x;
j2=y-L;
if(j2<1)
{
int add=1-j2;
add=abs(add);
j2+=add;
i2+=add;
}
i1=x+L;
j1=y;
if(i1>n)
{
int add=i1-n;
add=abs(add);
i1-=add;
j1-=add;
}
if(i1>=i2&&j1>=j2&&inside(i1,j1)&&inside(i2,j2))
maxim=max(maxim,query_st(i1,j1,i2,j2));
v.push_back(maxim);
}
for(int i=0;i<v.size();i++)
mini[i]=min(mini[i],v[i]);
}
int poz=1;
for(int i=0;i<=n+m;i++)
{
for(int a=poz;a<=mini[i];a++)
sol[a]=i;
poz=mini[i]+1;
}
for(int i=1;i<=n*m;i++)
cout<<sol[i]<<' ';
return 0;
}

View File

@@ -0,0 +1,26 @@
#include <bits/stdc++.h>
using namespace std;
int main()
{
int n;
cin >> n;
if (n == 1)
{
cout << "No";
return 0;
}
if (n % 3 == 0)
{
cout << 0 << ' ' << n / 3;
}
else if (n % 3 == 1)
{
cout << 2 << ' ' << (n - 4) / 3;
}
else
{
cout << 1 << ' ' << (n - 2) / 3;
}
}

View File

@@ -0,0 +1,70 @@
#include <bits/stdc++.h>
using namespace std;
#define int long long
int n,a[200005],b[200005];
int spa[200005],spb[200005];
int nxt[200005];
int rmq[200005][20];
int lg[200005];
int v[200005],spv[200005];
void calc_nxt()
{
///daca astept la poz i, astept la urmatoarea poz pentru care sum(a[j] de la i + 1 la p) > sum(b[j] de la i la p - 1)
///fie v[j] = a[j] - b[j - 1]
///de la pozitia i, astept la prima pozitie la care suma(v[j] de la i + 1 la p) > 0
///din sume partiale pe p, dupa pozitia i mai astept la prima pozitie cu spv[p] > spv[i]
for (int i = 1; i <= n; i++)
v[i] = a[i] - b[i - 1];
for (int i = 1; i <= n; i++)
spv[i] = spv[i - 1] + v[i];
spv[n + 1] = 1e18;
stack<int>s;
s.push(n + 1);
for (int i = n; i >= 1; i--)
{
while (spv[i] >= spv[s.top()])
s.pop();
nxt[i] = s.top();
s.push(i);
}
}
signed main()
{
ios_base::sync_with_stdio(false);
cin.tie(NULL);
cout.tie(NULL);
cin >> n;
for (int i = 1; i <= n; i++)
cin >> a[i],spa[i] = a[i] + spa[i - 1];
for (int i = 1; i <= n; i++)
cin >> b[i],spb[i] = b[i] + spb[i - 1];
calc_nxt();
for (int i = 0; i <= 19; i++)
rmq[n + 1][i] = n + 1;
for (int i = 2; i <= n; i++)
lg[i] = 1 + lg[i / 2];
for (int i = 1; i <= n; i++)
rmq[i][0] = nxt[i];
for (int j = 1; j <= lg[n]; j++)
for (int i = 1; i <= n; i++)
rmq[i][j] = rmq[rmq[i][j - 1]][j - 1];
int q;
cin >> q;
for (int i = 1; i <= q; i++)
{
int l,r;
cin >> l >> r;
int pos = l;
for (int j = lg[n]; j >= 0; j--)
if (rmq[pos][j] <= r)
pos = rmq[pos][j];
int timp = (spb[r] - spb[pos - 1]) - (spa[r] - spa[pos]);
cout << timp << '\n';
}
return 0;
}

View File

@@ -0,0 +1,60 @@
#include <bits/stdc++.h>
using namespace std;
#define int long long
int l,r,m;
int lgpow(int x,int y)
{
int z = 1;
while (y != 0)
{
if (y % 2 == 1)
z = z * x % m;
x = x * x % m;
y /= 2;
}
return z;
}
int sump2(int x)
{
return lgpow(2,x + 1) - 1;
}
void testcase()
{
cin >> l >> r >> m;
int ans = 0;
if (r - l + 1 <= 3)
{
for (int i = l; i <= r; i++)
ans += lgpow(2,(i - 1) / 2);
cout << ans % m << '\n';
}
else
{
if (l % 2 == 0)
ans += lgpow(2,(l - 1) / 2),l++;
if (r % 2 == 1)
ans += lgpow(2,(r - 1) / 2),r--;
int st = (l + 1) / 2,fin = (r / 2);
ans += sump2(fin) - sump2(st - 1);
ans += m;
cout << ans % m << '\n';
}
}
signed main()
{
ios_base::sync_with_stdio(false);
cin.tie(NULL);
cout.tie(NULL);
int tc;
cin >> tc;
while (tc--)
testcase();
return 0;
}

View File

@@ -0,0 +1,43 @@
#include <bits/stdc++.h>
using namespace std;
int mod;
long long pw(long long b, int e)
{
long long ans = 1;
while(e)
{
if(e & 1)
ans = (ans * b) % mod;
b = (b * b) % mod;
e >>= 1;
}
return ans;
}
long long solve(int x)
{
if(x % 2 == 0)
return (2LL * (pw(2, x/2) - 1)) % mod;
else
{
return (2LL * (pw(2, x/2) - 1) % mod + pw(2, x/2)) % mod;
}
}
int main()
{
ios_base::sync_with_stdio(false);
cin.tie(NULL);
int t;
cin >> t;
for(; t; t--)
{
int L, R;
cin >> L >> R >> mod;
cout << (solve(R) - solve(L-1) + mod) % mod << '\n';
}
return 0;
}

View File

@@ -0,0 +1,383 @@
#include <bits/stdc++.h>
using namespace std;
#ifdef LOCAL
ifstream fin("suceava.in");
ofstream fout("suceava.out");
#else
#define fin cin
#define fout cout
#endif
const int kN = 1e5;
const int kM = 1e5;
const int kT = 1e5;
const int kQ = 1e5;
const int kLog = 18;
const int kInf = 1e9;
const bool ERASE = 0;
const bool INSERT = 1;
vector<int> adj[kN], rmq[kLog + 1];
int tin[kN], depth[kN], lg2[kN << 1 | 1];
void maxSelf(int &x, int y) {
if(y > x) {
x = y;
}
}
void dfs(int u = 0, int v = 0) {
tin[u] = rmq[0].size();
rmq[0].emplace_back(u);
for(const auto &it: adj[u]) if(it != v) {
depth[it] = depth[u] + 1;
dfs(it, u);
rmq[0].emplace_back(u);
}
}
int _min(int u, int v) {
if(depth[u] < depth[v]) {
return u;
}
return v;
}
void init() {
dfs();
lg2[1] = 0;
for(int i = 2; i <= (int) rmq[0].size(); i++) {
lg2[i] = lg2[i >> 1] + 1;
}
int n = rmq[0].size();
for(int i = 1; (1 << i) <= n; i++) {
for(int j = 0; j + (1 << i) - 1 < n; j++) {
rmq[i].emplace_back(_min(rmq[i - 1][j], rmq[i - 1][j + (1 << (i - 1))]));
}
}
}
int query(int l, int r) {
int lg = lg2[r - l + 1];
return _min(rmq[lg][l], rmq[lg][r - (1 << lg) + 1]);
}
int lca(int u, int v) {
int l = tin[u], r = tin[v];
if(l > r) {
swap(l, r);
}
return query(l, r);
}
int dist(int u, int v) {
return depth[u] + depth[v] - 2 * depth[lca(u, v)];
}
struct Edge {
int u, v;
Edge() {}
Edge(int u, int v): u(u), v(v) {}
bool operator < (const Edge &oth) const {
if(u == oth.u) {
return v < oth.v;
}
return u < oth.u;
}
};
map<Edge, int> col;
struct Event {
bool t;
int time;
Edge edge;
Event(bool t, int time, Edge edge): t(t), time(time), edge(edge) {}
};
vector<Event> events[kN];
vector<pair<int, int>> res[kN];
struct DSU {
struct DSU_SAVE {
int u, v;
pair<int, int> diameter;
DSU_SAVE() {}
DSU_SAVE(int u, int v, pair<int, int> diameter): u(u), v(v), diameter(diameter) {}
};
int n;
vector<int> par, sz;
vector<pair<int, int>> diameter;
stack<DSU_SAVE> stk;
int mx;
DSU() {}
DSU(int n): n(n), par(n), sz(n), diameter(n) {
init();
}
void init() {
assert(stk.empty());
mx = 0;
for(int i = 0; i < n; i++) {
makeSet(i);
}
}
void makeSet(int u) {
par[u] = u;
sz[u] = 1;
diameter[u] = make_pair(u, u);
}
int findRoot(int u) {
if(par[u] == u) {
return u;
}
return findRoot(par[u]);
}
pair<int, int> findDiameter(int u) {
return diameter[findRoot(u)];
}
pair<int, int> join(int u, int v) {
pair<int, int> t1 = findDiameter(u);
pair<int, int> t2 = findDiameter(v);
vector<pair<int, int>> candidates = {
t1,
t2,
{t1.first, t2.first},
{t1.first, t2.second},
{t1.second, t2.first},
{t1.second, t2.second}
};
int max_dist = 0;
pair<int, int> res = candidates.front();
for(const auto &it: candidates) {
if(dist(it.first, it.second) > max_dist) {
res = it;
max_dist = dist(it.first, it.second);
}
}
maxSelf(mx, max_dist);
return res;
}
bool unite(int u, int v) {
u = findRoot(u);
v = findRoot(v);
if(u == v) {
return 0;
}
if(sz[u] > sz[v]) {
swap(u, v);
}
stk.emplace(u, v, diameter[v]);
diameter[v] = join(u, v);
par[u] = v;
sz[v] += sz[u];
return 1;
}
void undo() {
assert(!stk.empty());
int u = stk.top().u, v = stk.top().v;
pair<int, int> old_diameter = stk.top().diameter, crt_diameter = diameter[v];
int crt_dist = dist(crt_diameter.first, crt_diameter.second);
stk.pop();
par[u] = u;
sz[v] -= sz[u];
diameter[v] = old_diameter;
}
void undo_max(int newVal) {
mx = newVal;
}
int query() {
return mx;
}
};
DSU dsu;
vector<int> ans;
struct AINT {
int n;
vector<vector<Edge>> tree;
AINT() {}
AINT(int n): n(n), tree(n << 2 | 1) {}
void update(int a, int b, const Edge &edge, int node, int l, int r) {
if(a <= l && r <= b) {
tree[node].emplace_back(edge);
} else {
int mid = (l + r) >> 1;
if(a <= mid) {
update(a, b, edge, node << 1, l, mid);
}
if(b > mid) {
update(a, b, edge, node << 1 | 1, mid + 1, r);
}
}
}
void update(int a, int b, const Edge &edge) {
update(a, b, edge, 1, 0, n);
}
void solve(int node, int l, int r) {
int cnt = 0, prev_max = dsu.query();
for(const auto &it: tree[node]) {
cnt += dsu.unite(it.u, it.v);
}
if(l == r) {
ans[l] = dsu.query();
} else {
int mid = (l + r) >> 1;
solve(node << 1, l, mid);
solve(node << 1 | 1, mid + 1, r);
}
while(cnt--) {
dsu.undo();
}
dsu.undo_max(prev_max);
}
void solve() {
ans = vector<int>(n + 1);
solve(1, 0, n);
}
};
int main() {
fin.tie(nullptr)->sync_with_stdio(false);
int n, m;
assert(fin >> n >> m);
assert(2 <= n && n <= kN);
assert(2 <= m && m <= kM);
dsu = DSU(n);
for(int i = 1; i < n; i++) {
int u, v, c;
assert(fin >> u >> v >> c);
assert(1 <= u && u <= n);
assert(1 <= v && v <= n);
assert(1 <= c && c <= m);
u--; v--; c--;
if(u > v) {
swap(u, v);
}
col[Edge(u, v)] = c;
events[c].emplace_back(INSERT, 0, Edge(u, v));
adj[u].emplace_back(v);
adj[v].emplace_back(u);
}
int t;
assert(fin >> t);
assert(1 <= t && t <= kT);
for(int i = 1; i <= t; i++) {
int u, v, c;
assert(fin >> u >> v >> c);
assert(1 <= u && u <= n);
assert(1 <= v && v <= n);
assert(1 <= c && c <= m);
u--; v--; c--;
if(u > v) {
swap(u, v);
}
int lst_c = col[Edge(u, v)];
events[lst_c].emplace_back(ERASE, i, Edge(u, v));
col[Edge(u, v)] = c;
events[c].emplace_back(INSERT, i, Edge(u, v));
}
init();
for(int c = 0; c < m; c++) if(!events[c].empty()) {
map<Edge, int> timer;
AINT aint(events[c].size());
for(int i = 0; i < (int) events[c].size(); i++) {
Event ev = events[c][i];
if(ev.t == INSERT) {
if(timer.count(ev.edge) == 0) {
timer[ev.edge] = i;
}
} else {
aint.update(timer[ev.edge], i - 1, ev.edge);
timer.erase(ev.edge);
}
}
for(const auto &it: timer) {
aint.update(it.second, events[c].size(), it.first);
}
// dsu.init();
aint.solve();
int i = 0;
if(events[c][i].time == 0) {
while(i < (int) events[c].size() && events[c][i].time == 0) {
i++;
}
res[c].emplace_back(0, ans[i - 1]);
} else {
res[c].emplace_back(0, 0);
}
while(i < (int) events[c].size()) {
res[c].emplace_back(events[c][i].time, ans[i]);
i++;
}
}
int q;
assert(fin >> q);
assert(1 <= q && q <= kQ);
for(int i = 0; i < q; i++) {
int c, d;
assert(fin >> c >> d);
assert(1 <= c && c <= m);
assert(1 <= d && d <= t);
c--;
if(res[c].empty()) {
fout << "0\n";
} else {
auto it = upper_bound(res[c].begin(), res[c].end(), make_pair(d, kInf));
it = prev(it);
fout << it->second << '\n';
}
}
return 0;
}

View File

@@ -0,0 +1,308 @@
#include <bits/stdc++.h>
using namespace std;
ofstream out("f.out");
const int MOMMAX = 5e5;
struct edge
{
int ti,tf,x,y;
};
int n,m,t,q;
vector<int>g[100005];
map<pair<int,int>,int>color;
map<pair<int,int>,int>beg;
vector<edge>v[100005];
vector<pair<int,int>>qs[100005];///timp,index
vector<pair<int,int>>aint[4 * MOMMAX + 5];
vector<pair<int,int>>input_edges;
vector<int>inds[4 * MOMMAX + 5];
int ans[100005];
int diammax[4 * MOMMAX + 5];
int tata[100005],sz[100005],diam[100005];
pair<int,int>bestdiam[100005];
vector<int> rmq[19];
int tin[100005], depth[100005];
void _dfs(int u = 1, int v = 0) {
tin[u] = rmq[0].size();
rmq[0].emplace_back(u);
for(const auto &it: g[u]) if(it != v) {
depth[it] = depth[u] + 1;
_dfs(it, u);
rmq[0].emplace_back(u);
}
}
int _min(int u, int v) {
if(depth[u] < depth[v]) {
return u;
}
return v;
}
void init() {
_dfs();
int n = rmq[0].size();
for(int i = 1; (1 << i) <= n; i++) {
for(int j = 0; j + (1 << i) - 1 < n; j++) {
rmq[i].emplace_back(_min(rmq[i - 1][j], rmq[i - 1][j + (1 << (i - 1))]));
}
}
}
int query(int l, int r) {
int lg = __lg(r - l + 1);
return _min(rmq[lg][l], rmq[lg][r - (1 << lg) + 1]);
}
int lca(int u, int v) {
int l = tin[u], r = tin[v];
if(l > r) {
swap(l, r);
}
return query(l, r);
}
int dist(int u, int v) {
return depth[u] + depth[v] - 2 * depth[lca(u, v)];
}
void update(int nod,int l,int r,int st,int dr,pair<int,int>p)
{
if (r < st or dr < l)
return;
if (st <= l and r <= dr)
{
aint[nod].push_back(p);
return;
}
int mij = (l + r) / 2;
update(2 * nod,l,mij,st,dr,p);
update(2 * nod + 1,mij + 1,r,st,dr,p);
}
void setquery(int nod,int l,int r,int pos,int index)
{
if (l == r)
inds[nod].push_back(index);
else
{
int mij = (l + r) / 2;
if (pos <= mij)
setquery(2 * nod,l,mij,pos,index);
else
setquery(2 * nod + 1,mij + 1,r,pos,index);
}
}
struct stack_upd
{
int x,y,antx;
pair<int,int>antbestx;
///x a devenit tatal lui y
///x avea diam antx
///size-ul anterior al lui y o sa ramana in sz[y]
///diametrul anterior al lui y o sa ramane in diam[y]
};
stack<stack_upd>stk;
int reprez(int x)
{
while (x != tata[x])
x = tata[x];
return x;
}
void baga(int nod,int x,int y)
{
//cout << "super" << endl;
x = reprez(x);
y = reprez(y);
if (sz[x] < sz[y])
swap(x,y);
stack_upd aux;
aux.x = x;
aux.y = y;
aux.antbestx = bestdiam[x];
aux.antx = diam[x];
stk.push(aux);
tata[aux.y] = aux.x;
int maxim = max(diam[x],diam[y]);
maxim = max(maxim,dist(bestdiam[x].first,bestdiam[y].first));
maxim = max(maxim,dist(bestdiam[x].first,bestdiam[y].second));
maxim = max(maxim,dist(bestdiam[x].second,bestdiam[y].first));
maxim = max(maxim,dist(bestdiam[x].second,bestdiam[y].second));
//cout << x << ' ' << y << ' ' << diam[x] << ' ' << diam[y] << ' ' << dist(bestdiam[x].first,bestdiam[y].first) << ' ' << dist(bestdiam[x].first,bestdiam[y].second) << ' ' << dist(bestdiam[x].second,bestdiam[y].first) << ' ' << dist(bestdiam[x].second,bestdiam[y].second) << endl;
diammax[nod] = max(diammax[nod],maxim);
if (diam[x] == maxim)
{
return;
}
if (diam[y] == maxim)
{
diam[x] = diam[y];
bestdiam[x] = bestdiam[y];
return;
}
if (dist(bestdiam[x].first,bestdiam[y].first) == maxim)
{
diam[x] = dist(bestdiam[x].first,bestdiam[y].first);
bestdiam[x] = {bestdiam[x].first,bestdiam[y].first};
return;
}
if (dist(bestdiam[x].first,bestdiam[y].second) == maxim)
{
diam[x] = dist(bestdiam[x].first,bestdiam[y].second);
bestdiam[x] = {bestdiam[x].first,bestdiam[y].second};
return;
}
if (dist(bestdiam[x].second,bestdiam[y].first) == maxim)
{
diam[x] = dist(bestdiam[x].second,bestdiam[y].first);
bestdiam[x] = {bestdiam[x].second,bestdiam[y].first};
return;
}
if (dist(bestdiam[x].second,bestdiam[y].second) == maxim)
{
diam[x] = dist(bestdiam[x].second,bestdiam[y].second);
bestdiam[x] = {bestdiam[x].second,bestdiam[y].second};
return;
}
}
void rollback()
{
stack_upd aux = stk.top();
stk.pop();
tata[aux.y] = aux.y;
sz[aux.x] -= sz[aux.y];
diam[aux.x] = aux.antx;
bestdiam[aux.x] = aux.antbestx;
}
void dfs(int nod,int l,int r)
{
/*if (!aint[nod].empty())
{
cout << nod << ' ' << l << ' ' << r << endl;
for (auto it : aint[nod])
cout << it.first << ' ' << it.second << endl;
cout << endl;
}*/
diammax[nod] = diammax[nod / 2];
for (auto it : aint[nod])
baga(nod,it.first,it.second);
//if (!aint[nod].empty() or !inds[nod].empty())
// cout << nod << ' ' << l << ' ' << r << ' ' << diammax[nod] << '\n';
if (l == r)
{
for (auto it : inds[nod])
ans[it] = diammax[nod];
}
else
{
int mij = (l + r) / 2;
dfs(2 * nod,l,mij);
dfs(2 * nod + 1,mij + 1,r);
}
for (int i = 0; i < aint[nod].size(); i++)
rollback();
}
int main()
{
ios_base::sync_with_stdio(false);
cin.tie(NULL);
cout.tie(NULL);
cin >> n >> m;
for (int i = 1; i < n; i++)
{
int x,y,cc;
cin >> x >> y >> cc;
if (x > y)
swap(x,y);
color[{x,y}] = cc;
g[x].push_back(y);
g[y].push_back(x);
beg[{x,y}] = 1;
input_edges.push_back({x,y});
}
for (int i = 1; i <= n; i++)
tata[i] = i,sz[i] = 1,diam[i] = 0,bestdiam[i] = {i,i};
init();
cin >> t;
for (int i = 1; i <= t; i++)
{
int x,y,cc;
cin >> x >> y >> cc;
if (x > y)
swap(x,y);
edge aux;
aux.x = x;
aux.y = y;
aux.ti = beg[{x,y}];
aux.tf = i;
v[color[{x,y}]].push_back(aux);
color[{x,y}] = cc;
beg[{x,y}] = i + 1;
}
for (int i = 0; i < n - 1; i++)
{
int x = input_edges[i].first,y = input_edges[i].second;
edge aux;
aux.x = x;
aux.y = y;
aux.tf = t + 1;
aux.ti = beg[{x,y}];
v[color[{x,y}]].push_back(aux);
}
cin >> q;
for (int i = 1; i <= q; i++)
{
int cc,tmp;
cin >> cc >> tmp;
tmp++;
qs[cc].push_back({tmp,i});
}
int ft = 0;
for (int i = 1; i <= m; i++)
{
//cout << i << endl;
vector<int>vals;
for (auto it : v[i])
vals.push_back(it.ti),vals.push_back(it.tf);
for (auto it : qs[i])
vals.push_back(it.first);
sort(vals.begin(),vals.end());
if (vals.size() == 0)
continue;
map<int,int>mpnorma;
int posnorma = 0;
for (auto it : vals)
if (!mpnorma[it])
mpnorma[it] = ++posnorma;
for (int j = 0; j < v[i].size(); j++)
v[i][j].ti = mpnorma[v[i][j].ti] + ft,v[i][j].tf = mpnorma[v[i][j].tf] + ft;
for (int j = 0; j < qs[i].size(); j++)
qs[i][j].first = mpnorma[qs[i][j].first] + ft;
//for (auto it : v[i])
// cout << it.ti << ' ' << it.tf << ' ' << it.x << ' ' << it.y << endl;
//for (auto it : qs[i])
// cout << it.first << ' ' << it.second << endl;
for (int j = 0; j < v[i].size(); j++)
update(1,1,MOMMAX,v[i][j].ti,v[i][j].tf,{v[i][j].x,v[i][j].y});
for (int j = 0; j < qs[i].size(); j++)
setquery(1,1,MOMMAX,qs[i][j].first,qs[i][j].second);
ft += posnorma;
}
dfs(1,1,MOMMAX);
for (int i = 1; i <= q; i++)
cout << ans[i] << '\n';
return 0;
}

View File

@@ -0,0 +1,39 @@
#include <iostream>
#include <vector>
#include <algorithm>
#include <cassert>
#warning That's the baby, that's not my baby
typedef long long ll;
void solve() {
int n;
std::cin >> n;
ll sum = 0;
int maxi = 0;
for (int i = 0; i < n; i++) {
int x;
std::cin >> x;
if (i != n - 1) {
sum += x;
maxi = std::max(maxi, x);
}
}
std::cout << sum - maxi << '\n';
}
int main() {
std::ios_base::sync_with_stdio(false);
std::cin.tie(0);
int t;
std::cin >> t;
while (t--) {
solve();
}
return 0;
}

View File

@@ -0,0 +1,73 @@
#include <bits/stdc++.h>
//#pragma GCC optimize ("03")
#define FastIO ios_base::sync_with_stdio(false) , cin.tie(0) , cout.tie(0)
#define FILES freopen("in" , "r" , stdin) , freopen("out" , "w" , stdout)
#define ll long long
#define ull unsigned long long
#define ld long double
#define eb emplace_back
#define pb push_back
#define qwerty1 first
#define qwerty2 second
#define qwerty3 -> first
#define qwerty4 -> second
#define umap unordered_map
#define uset unordered_set
#define pii pair < ll , ll >
#define pq priority_queue
#define dbg(x) cerr << #x << ": " << x << '\n'
namespace FastRead
{
char __buff[5000];ll __lg = 0 , __p = 0;
char nc()
{
if(__lg == __p){__lg = fread(__buff , 1 , 5000 , stdin);__p = 0;if(!__lg) return EOF;}
return __buff[__p++];
}
template<class T>void read(T&__x)
{
T __sgn = 1; char __c;while(!isdigit(__c = nc()))if(__c == '-')__sgn = -1;
__x = __c - '0';while(isdigit(__c = nc()))__x = __x * 10 + __c - '0';__x *= __sgn;
}
}
using namespace FastRead;
using namespace std;
const ll N = 2e5 + 10;
const ll M = 1e9 + 7;
const ld PI = acos(-1);
mt19937 rng(chrono::steady_clock::now().time_since_epoch().count());
ll n;
ll a[N];
void Test()
{
ll i , sum = 0;
cin >> n;
for(i = 1 ; i <= n ; i++)
cin >> a[i] , sum += a[i];
ll mx = -1;
for(i = 1 ; i < n ; i++)
mx = max(mx , a[i]);
cout << sum - a[n] - mx << '\n';
}
signed main()
{
#ifndef ONLINE_JUDGE
FastIO , FILES;
#endif
ll q; cin >> q;
while(q--) Test();
return 0;
}

View File

@@ -0,0 +1,108 @@
#include <bits/stdc++.h>
using namespace std;
#define int long long
const int inf = 1e18;
int n;
struct gand
{
int x,y,val;
};
gand a[200005];
int max_pxpy[200005];
int max_pxmy[200005];
int max_mxpy[200005];
int max_mxmy[200005];
int max_px[200005];
int max_py[200005];
int max_mx[200005];
int max_my[200005];
void prec()
{
for (int i = 1; i <= 200000; i++)
max_pxpy[i] = max_pxmy[i] = max_mxpy[i] = max_mxmy[i] = max_px[i] = max_py[i] = max_mx[i] = max_my[i] = -inf;
for (int i = 1; i <= n; i++)
{
int vl = a[i].val,x = a[i].x,y = a[i].y;
max_pxpy[vl] = max(max_pxpy[vl],x + y);
max_pxmy[vl] = max(max_pxmy[vl],x - y);
max_mxpy[vl] = max(max_mxpy[vl],-x + y);
max_mxmy[vl] = max(max_mxmy[vl],-x - y);
max_px[vl] = max(max_px[vl],x);
max_py[vl] = max(max_py[vl],y);
max_mx[vl] = max(max_mx[vl],-x);
max_my[vl] = max(max_my[vl],-y);
}
}
signed main()
{
ios_base::sync_with_stdio(false);
cin.tie(NULL);
cout.tie(NULL);
cin >> n;
for (int i = 1; i <= n; i++)
cin >> a[i].x >> a[i].y >> a[i].val;
prec();
int t;
cin >> t;
while (t--)
{
int m;
cin >> m;
vector<int>v(m + 1);
vector<vector<int>>dp(m + 1);
for (int i = 1; i <= m; i++)
cin >> v[i];
for (int i = 1; i <= m; i++)
dp[i].resize(5);
dp[1][0] = 0;
dp[1][1] = max_pxpy[v[1]];
dp[1][2] = max_pxmy[v[1]];
dp[1][3] = max_mxpy[v[1]];
dp[1][4] = max_mxmy[v[1]];
//cout << dp[1][0] << ' ' << dp[1][1] << ' ' << dp[1][2] << ' ' << dp[1][3] << ' ' << dp[1][4] << '\n';
for (int i = 2; i <= m; i++)
{
int val0 = -inf;
val0 = max(val0,dp[i - 1][1] + max_mxmy[v[i]]);
val0 = max(val0,dp[i - 1][2] + max_mxpy[v[i]]);
val0 = max(val0,dp[i - 1][3] + max_pxmy[v[i]]);
val0 = max(val0,dp[i - 1][4] + max_pxpy[v[i]]);
dp[i][0] = val0;
int val1 = -inf;
val1 = max(val1,dp[i - 1][1]);
val1 = max(val1,dp[i - 1][2] + 2 * max_py[v[i]]);
val1 = max(val1,dp[i - 1][3] + 2 * max_px[v[i]]);
val1 = max(val1,dp[i - 1][4] + 2 * max_pxpy[v[i]]);
dp[i][1] = val1;
int val2 = -inf;
val2 = max(val2,dp[i - 1][1] + 2 * max_my[v[i]]);
val2 = max(val2,dp[i - 1][2]);
val2 = max(val2,dp[i - 1][3] + 2 * max_pxmy[v[i]]);
val2 = max(val2,dp[i - 1][4] + 2 * max_px[v[i]]);
dp[i][2] = val2;
int val3 = -inf;
val3 = max(val3,dp[i - 1][1] + 2 * max_mx[v[i]]);
val3 = max(val3,dp[i - 1][2] + 2 * max_mxpy[v[i]]);
val3 = max(val3,dp[i - 1][3]);
val3 = max(val3,dp[i - 1][4] + 2 * max_py[v[i]]);
dp[i][3] = val3;
int val4 = -inf;
val4 = max(val4,dp[i - 1][1] + 2 * max_mxmy[v[i]]);
val4 = max(val4,dp[i - 1][2] + 2 * max_mx[v[i]]);
val4 = max(val4,dp[i - 1][3] + 2 * max_my[v[i]]);
val4 = max(val4,dp[i - 1][4]);
dp[i][4] = val4;
//cout << dp[i][0] << ' ' << dp[i][1] << ' ' << dp[i][2] << ' ' << dp[i][3] << ' ' << dp[i][4] << '\n';
}
cout << dp[m][0] << '\n';
}
return 0;
}

View File

@@ -0,0 +1,132 @@
#include <bits/stdc++.h>
using namespace std;
#define int long long
const int inf = 1e18;
int n;
struct gand
{
int x,y,val;
};
gand a[200005];
int max_pxpy[200005];
int max_pxmy[200005];
int max_mxpy[200005];
int max_mxmy[200005];
int max_px[200005];
int max_py[200005];
int max_mx[200005];
int max_my[200005];
void prec()
{
for (int i = 1; i <= 200000; i++)
max_pxpy[i] = max_pxmy[i] = max_mxpy[i] = max_mxmy[i] = max_px[i] = max_py[i] = max_mx[i] = max_my[i] = -inf;
for (int i = 1; i <= n; i++)
{
int vl = a[i].val,x = a[i].x,y = a[i].y;
max_pxpy[vl] = max(max_pxpy[vl],x + y);
max_pxmy[vl] = max(max_pxmy[vl],x - y);
max_mxpy[vl] = max(max_mxpy[vl],-x + y);
max_mxmy[vl] = max(max_mxmy[vl],-x - y);
max_px[vl] = max(max_px[vl],x);
max_py[vl] = max(max_py[vl],y);
max_mx[vl] = max(max_mx[vl],-x);
max_my[vl] = max(max_my[vl],-y);
}
}
signed main()
{
ios_base::sync_with_stdio(false);
cin.tie(NULL);
cout.tie(NULL);
cin >> n;
for (int i = 1; i <= n; i++)
cin >> a[i].x >> a[i].y >> a[i].val;
prec();
int t;
cin >> t;
while (t--)
{
int m;
cin >> m;
vector<int>v(m + 1);
vector<vector<int>>dp(m + 1);
for (int i = 1; i <= m; i++)
cin >> v[i];
for (int i = 1; i <= m; i++)
dp[i].resize(5);
dp[1][0] = 0;
dp[1][1] = max_pxpy[v[1]];
dp[1][2] = max_pxmy[v[1]];
dp[1][3] = max_mxpy[v[1]];
dp[1][4] = max_mxmy[v[1]];
//cout << dp[1][0] << ' ' << dp[1][1] << ' ' << dp[1][2] << ' ' << dp[1][3] << ' ' << dp[1][4] << '\n';
for (int i = 2; i <= m; i++)
{
int val0 = -inf;
val0 = max(val0,dp[i - 1][1] + max_mxmy[v[i]]);
val0 = max(val0,dp[i - 1][2] + max_mxpy[v[i]]);
val0 = max(val0,dp[i - 1][3] + max_pxmy[v[i]]);
val0 = max(val0,dp[i - 1][4] + max_pxpy[v[i]]);
dp[i][0] = val0;
int val1 = -inf;
val1 = max(val1,dp[i - 1][1]);
val1 = max(val1,dp[i - 1][2] + 2 * max_py[v[i]]);
val1 = max(val1,dp[i - 1][3] + 2 * max_px[v[i]]);
val1 = max(val1,dp[i - 1][4] + 2 * max_pxpy[v[i]]);
dp[i][1] = val1;
int val2 = -inf;
val2 = max(val2,dp[i - 1][1] + 2 * max_my[v[i]]);
val2 = max(val2,dp[i - 1][2]);
val2 = max(val2,dp[i - 1][3] + 2 * max_pxmy[v[i]]);
val2 = max(val2,dp[i - 1][4] + 2 * max_px[v[i]]);
dp[i][2] = val2;
int val3 = -inf;
val3 = max(val3,dp[i - 1][1] + 2 * max_mx[v[i]]);
val3 = max(val3,dp[i - 1][2] + 2 * max_mxpy[v[i]]);
val3 = max(val3,dp[i - 1][3]);
val3 = max(val3,dp[i - 1][4] + 2 * max_py[v[i]]);
dp[i][3] = val3;
int val4 = -inf;
val4 = max(val4,dp[i - 1][1] + 2 * max_mxmy[v[i]]);
val4 = max(val4,dp[i - 1][2] + 2 * max_mx[v[i]]);
val4 = max(val4,dp[i - 1][3] + 2 * max_my[v[i]]);
val4 = max(val4,dp[i - 1][4]);
dp[i][4] = val4;
//cout << dp[i][0] << ' ' << dp[i][1] << ' ' << dp[i][2] << ' ' << dp[i][3] << ' ' << dp[i][4] << '\n';
}
cout << dp[m][0] << '\n';
}
return 0;
}
/**
0 -> nimic
1 -> +x+y
2 -> +x-y
3 -> -x+y
4 -> -x-y
**/
/**
10
4 7 15670
19 2 33967
-10 -4 25333
-3 6 57312
2 -6 191291
0 -8 152287
-1 4 161306
17 1 177377
3 -20 74203
20 -5 37760
1
5 152287 74203 74203 74203 37760
**/

View File

@@ -0,0 +1,81 @@
#include <bits/stdc++.h>
using namespace std;
#define int long long
const int modulo = 1e9 + 7;
int k,s,t;
int fact[5000005],invfact[5000005];
int C(int x,int y)
{
if (x < y)
return 0;
if (y < 0)
return 0;
return fact[x] * invfact[y] % modulo * invfact[x - y] % modulo;
}
int f(int x,int y)
{
if (x < y)
return 0;
if (x == 0 and y == 0)
return 1;
if (y == 0)
return 0;
///in cate moduri pot distribui x in y numere pozitive
///in cate moduri pot pune y - 1 bare in x - 1 pozitii cu oricare doua bare diferite
///C(x - 1,y - 1)
return C(x - 1,y - 1);
}
int lgpow(int x,int y)
{
int z = 1;
while (y != 0)
{
if (y % 2 == 1)
z = z * x % modulo;
x = x * x % modulo;
y /= 2;
}
return z;
}
void prec()
{
fact[0] = invfact[0] = 1;
for (int i = 1; i <= 5e6; i++)
fact[i] = i * fact[i - 1] % modulo;
invfact[(int)5e6] = lgpow(fact[(int)5e6],modulo - 2);
for (int i = 5e6 - 1; i >= 1; i--)
invfact[i] = invfact[i + 1] * (i + 1) % modulo;
}
signed main()
{
prec();
cin >> k >> s >> t;
int d = k / t,r = k % t;
int ans = 0;
for (int x = 0; x <= s / (d + 1); x++)
{
if ((s - (d + 1) * x) % d == 0)
ans = (ans + f(x,r) * f((s - (d + 1) * x) / d,t - r)) % modulo;
}
cout << ans;
return 0;
}
/**
int d = k / t,r = k % t
(d + 1)(a[1] + a[2] + ... + a[r]) + d(a[r + 1] + ... + a[k])
fie x = a[1] + ... + a[r]
pentru fiecare x posibil, avem:
0 daca (s - (d + 1)x) % d != 0
f(x,r) * f((s - (d + 1)x) / d,k - r) altfel
si avem suma din asta
**/

View File

@@ -0,0 +1,102 @@
#include <iostream>
#include <vector>
#include <algorithm>
#include <cassert>
#warning That's the baby, that's not my baby
typedef long long ll;
/**
b[0] = a[1] = a[t + 1] = a[2 * t + 1] = ...
b[1] = a[2] = a[t + 2] = a[2 * t + 2] = ...
b[2] = a[3] = a[t + 3] = a[2 * t + 3] = ...
b[0] * x + b[1] * x + ... + b[i] * x + b[i + 1] * (x - 1) + b[i + 2] * (x - 1) + ... b[t - 1] * (x - 1) = s
x * (b[0] + b[1] + ... + b[i]) + (x - 1) * (b[i + 1] + b[i + 2] + ... + b[t - 1]) = s
i = k % t, x = k / t + 1
x * a + b * (x - 1) = s
**/
const int mod = 1e9 + 7;
const int NMAX = 1e7;
int fac[NMAX + 1], ifac[NMAX + 1];
int power(int a, int b) {
int p = 1;
while (b) {
if (b & 1) {
p = (ll) p * a % mod;
}
a = (ll) a * a % mod;
b >>= 1;
}
return p;
}
int C(int n, int k) {
if (n < k) {
return 0;
}
return (ll) fac[n] * ifac[k] % mod * ifac[n - k] % mod;
}
int sb(int n, int k) {
return C(k - 1, n - 1);
}
int main() {
fac[0] = 1;
for (int i = 1; i <= NMAX; i++) {
fac[i] = (ll) fac[i - 1] * i % mod;
}
ifac[NMAX] = power(fac[NMAX], mod - 2);
for (int i = NMAX - 1; i >= 0; i--) {
ifac[i] = (ll) ifac[i + 1] * (i + 1) % mod;
}
for (int i = 0; i <= NMAX; i++) {
assert((ll) fac[i] * ifac[i] % mod == 1);
}
int k, s, t;
std::cin >> k >> s >> t;
int i = k % t, x = k / t + 1; // x >= 2
if (i == 0) {
if (s % (x - 1) != 0) {
std::cout << 0;
} else {
std::cout << sb(t, s / (x - 1));
}
return 0;
}
/// x * a + b * (x - 1) = s
int answer = 0;
for (int a = 0; a * x <= s; a++) {
int b = s - a * x;
if (b % (x - 1) != 0) {
continue;
}
b /= x - 1;
/// a = suma primelor i, b = suma ultimelor t - i
answer += (ll) sb(i, a) * sb(t - i, b) % mod;
if (answer >= mod) {
answer -= mod;
}
}
std::cout << answer;
return 0;
}

View File

@@ -0,0 +1,45 @@
#include <iostream>
#include <vector>
#include <algorithm>
#include <cassert>
#warning That's the baby, that's not my baby
typedef long long ll;
void solve() {
int n;
std::cin >> n;
int f[n] = {};
for (int i = 0; i < n; i++) {
int x;
std::cin >> x;
--x;
f[x]++;
}
int gr4 = 0, gr2 = 0;
for (int i = 0; i < n; i++) {
if (f[i] >= 4) {
gr4++;
} else if (f[i] >= 2) {
gr2++;
}
}
if (gr4 > 0 || gr2 >= 2) {
std::cout << "YES\n";
} else {
std::cout << "NO\n";
}
}
int main() {
std::ios_base::sync_with_stdio(false);
std::cin.tie(0);
int t;
std::cin >> t;
while (t--) {
solve();
}
return 0;
}

View File

@@ -0,0 +1,289 @@
#include <bits/stdc++.h>
using namespace std;
#define int long long
int n,v[200005];
int ans;
void solvell(int l,int r)///ambele in stanga
{
int mij = (l + r) / 2;
int rmax = mij + 1;
int maxst = 0,minst = 1e9;
for (int i = mij; i >= l; i--)
{
maxst = max(maxst,v[i]);
minst = min(minst,v[i]);
while (rmax <= r and v[rmax] <= maxst and v[rmax] >= minst)
rmax++;
int topr = maxst - minst + i;
int rreal = min(topr,rmax - 1);
ans += max(0ll,rreal - mij);
}
}
void solverr(int l,int r)///ambele in dreapta
{
int mij = (l + r) / 2;
int lmax = mij;
int maxdr = 0,mindr = 1e9;
for (int i = mij + 1; i <= r; i++)
{
maxdr = max(maxdr,v[i]);
mindr = min(mindr,v[i]);
while (lmax >= l and v[lmax] < maxdr and v[lmax] > mindr)
lmax--;
int topl = i - maxdr + mindr;
int lreal = max(topl,lmax + 1);
ans += max(0ll,mij - lreal + 1);
}
}
struct ura
{
int l,r,val;
};
vector<ura>queries;
void addquery(int l,int r,int val)
{
ura aux;
aux.l = l;
aux.r = r;
aux.val = val;
queries.push_back(aux);
}
int aib[200005];
vector<pair<int,int>>updates;
void update(int pos,int val)
{
for (int i = pos; i <= n; i += (i & -i))
aib[i] += val;
}
int query(int pos)
{
int x = 0;
for (int i = pos; i > 0; i -= (i & -i))
x += aib[i];
return x;
}
void upd(int pos,int val)
{
updates.push_back({pos,val});
update(pos,val);
}
void resetaib()
{
for (auto it : updates)
update(it.first,-it.second);
updates.clear();
}
bool cmp(ura A,ura B)
{
return A.val < B.val;
}
void solvequeries(int l,int r)
{
sort(queries.begin(),queries.end(),cmp);
vector<pair<int,int>>values;
int mxx = 0;
int mij = (l + r) / 2;
for (int i = mij + 1; i <= r; i++)
{
mxx = max(mxx,v[i]);
values.push_back({i - mxx,i});
}
sort(values.begin(),values.end());
int i1 = 0;
for (int i = 0; i < queries.size(); i++)
{
while (i1 < values.size() and values[i1].first <= queries[i].val)
upd(values[i1].second,1ll),i1++;
ans += query(queries[i].r) - query(queries[i].l - 1);
}
resetaib();
}
void solvelr(int l,int r)///min in stanga,max in dreapta
{
int mij = (l + r) / 2;
int maxst = 0,minst = 1e9;
vector<int>premax(r - mij + 2);
premax[1] = v[mij + 1];
for (int i = mij + 2; i <= r; i++)
premax[i - mij] = max(premax[i - mij - 1],v[i]);
int rmin = mij + 1,rmax = mij + 1;///nu se poate r < rmin fiindca nu ar mai fi max in dreapta, nu se poate r >= rmax fiindca ar fi min in dreapta
for (int i = mij; i >= l; i--)
{
maxst = max(maxst,v[i]);
minst = min(minst,v[i]);
while (rmin <= r and premax[rmin - mij] <= maxst)
rmin++;
while (rmax <= r and v[rmax] >= minst)
rmax++;
//if (l == 1 and r == 10)
// cout << i << ' ' << rmin << ' ' << rmax << '\n';
if (rmin <= rmax - 1)
{
///ma intreb cate valori intre rmin si rmax - 1 sunt valide
///o valoare e valida daca r - maxpref[r] <= l - minst
addquery(rmin,rmax - 1,i - minst);
}
}
solvequeries(l,r);
queries.clear();
}
struct ura2
{
int l,r,val;
};
vector<ura2>queries2;
void addquery2(int l,int r,int val)
{
ura2 aux;
aux.l = l;
aux.r = r;
aux.val = val;
queries2.push_back(aux);
}
int aib2[200005];
vector<pair<int,int>>updates2;
void update2(int pos,int val)
{
for (int i = pos; i <= 2 * n; i += (i & -i))
aib2[i] += val;
}
int query2(int pos)
{
int x = 0;
for (int i = pos; i > 0; i -= (i & -i))
x += aib2[i];
return x;
}
void upd2(int pos,int val)
{
updates2.push_back({pos,val});
update2(pos,val);
}
void resetaib2()
{
for (auto it : updates2)
update2(it.first,-it.second);
updates2.clear();
}
bool cmp2(ura2 A, ura2 B)
{
return A.val < B.val;
}
void solvequeries2(int l,int r)
{
sort(queries2.begin(),queries2.end(),cmp2);
vector<pair<int,int>>values;
int mij = (l + r) / 2;
int mxx = 0;
for (int i = mij; i >= l; i--)
{
mxx = max(mxx,v[i]);
values.push_back({i + mxx,i});
}
sort(values.begin(),values.end());
int i1 = 0;
for (int i = 0; i < queries2.size(); i++)
{
while (i1 < values.size() and values[i1].first < queries2[i].val)
upd2(values[i1].second,1),i1++;
ans += (queries2[i].r - queries2[i].l + 1);
ans -= (query2(queries2[i].r) - query2(queries2[i].l - 1));
}
resetaib2();
}
void solverl(int l,int r)///min in dreapta,max in stanga
{
int mij = (l + r) / 2;
int maxdr = 0,mindr = 1e9;
vector<int>sufmax(mij - l + 2);
sufmax[mij - l + 1] = v[mij];
for (int i = mij - 1; i >= l; i--)
sufmax[i - l + 1] = max(sufmax[i - l + 2],v[i]);
int lmin = mij,lmax = mij;///nu se poate l > lmax fiindca nu ar mai fi max in stanga, nu se poate l <= lmin fiindca ar fi min in stanga
for (int i = mij + 1; i <= r; i++)
{
maxdr = max(maxdr,v[i]);
mindr = min(mindr,v[i]);
while (lmax >= l and sufmax[lmax - l + 1] < maxdr)
lmax--;
while (lmin >= l and v[lmin] > mindr)
lmin--;
//if (l == 1 and r == 9)
// cout << i << ' '<< lmin << ' ' << lmax << '\n';
if (lmin + 1 <= lmax)
{
///ma intreb cate valori intre lmin + 1 si lmax sunt valide
///o valoare e valida daca l + maxsuf[l] >= r + mindr
addquery2(lmin + 1,lmax,i + mindr);
}
}
solvequeries2(l,r);
queries2.clear();
}
void solve(int l,int r)
{
if (l > r)
return;
if (l == r)
{
ans++;
return;
}
int mij = (l + r) / 2;
solve(l,mij);
solve(mij + 1,r);
//cout << l << ' ' << r << ' ';
solvell(l,r);
//cout << ans - d1 << ' ';
solverr(l,r);
//cout << ans - d1 << ' ';
solvelr(l,r);
//cout << ans - d1 << ' ';
solverl(l,r);
//cout << ans - d1 << '\n';
}
signed main()
{
ios_base::sync_with_stdio(false);
cin.tie(NULL);
cout.tie(NULL);
cin >> n;
for (int i = 1; i <= n; i++)
cin >> v[i];
solve(1,n);
cout << ans;
return 0;
}

View File

@@ -0,0 +1,166 @@
#include <bits/stdc++.h>
#define int long long
using namespace std;
struct rmq
{
vector<vector<int>> rmq;
vector<int> lg;
void build(vector<int> a)
{
int n = a.size() - 1;
lg = vector<int>(n + 1);
for (int i = 2; i <= n; ++i)
{
lg[i] = lg[i / 2] + 1;
}
rmq = vector<vector<int>>(n + 1, vector<int>(lg[n] + 1));
for (int i = 1; i <= n; ++i)
{
rmq[i][0] = a[i];
}
for (int j = 1; j <= lg[n]; ++j)
{
for (int i = 1; i + (1 << j) - 1 <= n; ++i)
{
rmq[i][j] = min(rmq[i][j - 1], rmq[i + (1 << (j - 1))][j - 1]);
}
}
}
int query(int st, int dr)
{
int pow_2 = lg[dr - st + 1];
return min(rmq[st][pow_2], rmq[dr - (1 << pow_2) + 1][pow_2]);
}
};
const int nmax = 2e5;
const int vmax = 2e5;
struct aib
{
int n;
vector<int> a;
void resize(int _n)
{
n = _n;
a = vector<int>(n + 1);
}
void update(int pos, int val)
{
for (int i = pos; i <= n; i += i & (-i))
{
a[i] += val;
}
}
void clear(int pos)
{
for (int i = pos; i <= n; i += i & (-i))
{
a[i] = 0;
}
}
int query(int pos)
{
if (pos < 0)
{
return 0;
}
int ans = 0;
for (int i = pos; i; i -= i & (-i))
{
ans += a[i];
}
return ans;
}
};
vector<int> a;
aib tree;
rmq adam;
int divide(int st, int dr)
{
if (st == dr)
{
return 1;
}
int mid = (st + dr) / 2;
int ans = divide(st, mid) + divide(mid + 1, dr);
int p1 = mid + 1, p2 = mid + 1;
int maxi = 0, mini = INT_MAX;
for (int i = mid; i >= st; --i)
{
maxi = max(maxi, a[i]);
mini = min(mini, a[i]);
while (p2 <= dr && a[p2] <= maxi)
{
tree.update(adam.query(mid + 1, p2) + (p2 - mid), 1);
p2++;
}
while (p1 <= dr && a[p1] >= mini)
{
tree.update(adam.query(mid + 1, p1) + (p1 - mid), -1);
p1++;
}
int l = p1, r = p2 - 1;
if (l <= r)
{
ans += tree.query(maxi - (mid - i + 1) + 1);
}
int cnt = min(l, r + 1) - (mid + 1);
ans += max(0ll, min(cnt, maxi - mini + 1 - (mid - i + 1)));
}
for (int i = mid + 1; i <= dr; ++i)
{
tree.clear(adam.query(mid + 1, i) + (i - mid));
}
p1 = mid, p2 = mid;
maxi = 0, mini = INT_MAX;
for (int i = mid + 1; i <= dr; ++i)
{
maxi = max(maxi, a[i]);
mini = min(mini, a[i]);
while (p2 >= st && a[p2] < maxi)
{
tree.update(adam.query(p2, mid) + (mid - p2 + 1), 1);
p2--;
}
while (p1 >= st && a[p1] >= mini)
{
tree.update(adam.query(p1, mid) + (mid - p1 + 1), -1);
p1--;
}
int l = p2 + 1, r = p1;
if (l <= r)
{
ans += tree.query(maxi - (i - mid) + 1);
}
int cnt = mid - max(l - 1, r);
ans += max(0ll, min(cnt, maxi - mini + 1 - (i - mid)));
}
for (int i = mid; i >= st; --i)
{
tree.clear(adam.query(i, mid) + (mid - i + 1));
}
return ans;
}
int32_t main()
{
cin.tie(nullptr)->sync_with_stdio(false);
int n;
cin >> n;
a = vector<int>(n + 1);
for (int i = 1; i <= n; ++i)
{
cin >> a[i];
}
adam.build(a);
tree.resize(nmax + vmax);
cout << divide(1, n);
}

View File

@@ -0,0 +1,92 @@
#include <cstdio>
#include <algorithm>
#include <cassert>
#define NRINT (100'000 + 5)
using namespace std;
struct interval
{
int apa, timpapa, inceput;
};
struct preferinte
{
int apa, timpdus;
};
int tmin[1500000];
int tnext[21][NRINT];
int nrinterv[21];
interval dus[NRINT];
preferinte om[21];
int log2[1500000];
inline int lsb(int val)
{
return val&(-val);
}
int bs(int val, int pers)
{
int st, dr, mid, last;
st = 0;
dr = nrinterv[pers];
while(st <= dr)
{
mid = (st + dr) / 2;
if(dus[tnext[pers][mid]].inceput > val)
dr = mid - 1;
else
{
last = mid;
st = mid + 1;
}
}
return last;
}
int main()
{
// freopen("dush.in", "r", stdin);
// freopen("dush.out", "w", stdout);
int n, m, i, j, missing, pozc, nex;
scanf("%d%d", &n, &m);
for(i = 1; i <= n; ++ i)
scanf("%d%d", &om[i].apa, &om[i].timpdus);
for(i = 1; i <= m; ++ i)
scanf("%d%d%d", &dus[i].inceput, &dus[i].timpapa, &dus[i].apa);
for(i = 1; i <= m; ++ i)
{
for(j = 1; j <= n; ++ j)
if(dus[i].apa == om[j].apa && dus[i].timpapa >= om[j].timpdus)
tnext[j][++ nrinterv[j]] = i;
}
for(i = 1; i < 1500000; ++ i)
tmin[i] = 2000000000;
for(i = 2; i <= (1 << n); ++ i)
log2[i] = log2[i/2] + 1;
for(i = 0; i < (1 << n); ++ i)
{
missing = ((1 << n) - 1) ^ i;
while(missing)
{
nex = lsb(missing);
j = log2[nex] + 1;
pozc = bs(tmin[i], j);
if(pozc > 0)
if(dus[tnext[j][pozc]].inceput + dus[tnext[j][pozc]].timpapa >= tmin[i] + om[j].timpdus)
if(tmin[i] + om[j].timpdus < tmin[i ^ nex])
tmin[i ^ nex] = tmin[i] + om[j].timpdus;
if(pozc < nrinterv[j])
if(tmin[i ^ nex] > dus[tnext[j][pozc + 1]].inceput + om[j].timpdus)
tmin[i ^ nex] = dus[tnext[j][pozc + 1]].inceput + om[j].timpdus;
missing ^= nex;
}
}
printf("%d", tmin[(1 << n) - 1]);
assert(tmin[(1 << n) - 1] < 2'000'000'000);
return 0;
}

View File

@@ -0,0 +1,88 @@
#include <bits/stdc++.h>
using namespace std;
#define int long long
const int inf = 1e18;
int n,m;
int tip[25],a[25];
int s[100005],d[100005],t[100005];
int dp[(1 << 20) + 5];///timpul minim la care mask isi fac dus
vector<pair<int,int>>interv[3];
int topt[25][100005];
void prec()
{
for (int om = 0; om < n; om++)
{
int tp = tip[om];
int lg = a[om];
topt[om][interv[tp].size()] = inf;
for (int i = interv[tp].size() - 1; i >= 0; i--)
{
topt[om][i] = topt[om][i + 1];
if (interv[tp][i].second >= lg)
topt[om][i] = interv[tp][i].first + lg;
}
}
}
int f(int ti,int om)
{
if (ti == inf)
return inf;
int st = -1,pas = 1 << 16;
while (pas != 0)
{
if (st + pas < interv[tip[om]].size() and interv[tip[om]][st + pas].first <= ti)
st += pas;
pas /= 2;
}
///st este ultimul interval cu s <= ti
int timp = inf;
if (st != -1)
{
if (interv[tip[om]][st].first + interv[tip[om]][st].second - ti >= a[om])
timp = ti + a[om];
}
if (timp == inf and st + 1 != interv[tip[om]].size())
{
timp = topt[om][st + 1];
}
//cout << ti << ' ' << om << ' ' << timp << '\n';
return timp;
}
signed main()
{
ios_base::sync_with_stdio(false);
cin.tie(NULL);
cout.tie(NULL);
cin >> n >> m;
for (int i = 0; i < n; i++)
cin >> tip[i] >> a[i],tip[i]++;
for (int i = 1; i <= m; i++)
{
cin >> s[i] >> d[i] >> t[i],t[i]++;
interv[t[i]].push_back({s[i],d[i]});
}
prec();
for (int mask = 1; mask < (1 << n); mask++)
{
int minim = inf;
for (int bit = 0; bit < n; bit++)
{
if ((mask & (1 << bit)) != 0)
{
int tant = dp[mask - (1 << bit)];
minim = min(minim,f(tant,bit));
}
}
dp[mask] = minim;
//cout << dp[mask] << '\n';
}
cout << dp[(1 << n) - 1];
return 0;
}

View File

@@ -0,0 +1,393 @@
#include <bits/stdc++.h>
using namespace std;
#ifdef LOCAL
ifstream fin("dragons.in");
ofstream fout("dragons.out");
#else
#define fin cin
#define fout cout
#endif
void YN(bool cond) {
if(cond) {
fout << "YES\n";
} else {
fout << "NO\n";
}
}
const int kV = 1000;
const int kQ = 1e4;
const int kN = 1e4;
const int kLog = 14;
const int kS = 1000;
const int kB = /*2 * kN / sqrt(kQ)*/ 120;
int weight[kN];
vector<int> plusminus;
int tin[kN], tout[kN];
vector<int> adj[kN];
int par[kN][kLog + 1], rmq[kN][kLog + 1];
void dfs(int u = 0, int v = 0) {
plusminus.emplace_back(u);
tin[u] = plusminus.size() - 1;
par[u][0] = v;
rmq[u][0] = weight[u];
for(int i = 1; i <= kLog; i++) {
par[u][i] = par[par[u][i - 1]][i - 1];
rmq[u][i] = max(rmq[u][i - 1], rmq[par[u][i - 1]][i - 1]);
}
for(const auto &it: adj[u]) if(it != v) {
dfs(it, u);
}
plusminus.emplace_back(u);
tout[u] = plusminus.size() - 1;
}
bool upper(int u, int v) {
return tin[u] <= tin[v] && tin[v] <= tout[u];
}
int lcaQuery(int u, int v) {
if(upper(u, v)) {
return u;
}
if(upper(v, u)) {
return v;
}
for(int i = kLog; i >= 0; i--) {
if(par[u][i] && !upper(par[u][i], v)) {
u = par[u][i];
}
}
return par[u][0];
}
void maxSelf(int &x, int y) {
if(y > x) {
x = y;
}
}
int maxQuery(int u, int v) {
if(upper(u, v)) {
swap(u, v);
}
int ret = 0;
for(int i = kLog; i >= 0; i--) {
if(par[u][i] && !upper(par[u][i], v)) {
maxSelf(ret, rmq[u][i]);
u = par[u][i];
}
}
maxSelf(ret, rmq[u][0]);
return ret;
}
int maxChain(int u, int v) {
int lca = lcaQuery(u, v), res = weight[lca];
maxSelf(res, maxQuery(u, lca));
maxSelf(res, maxQuery(v, lca));
return res;
}
struct Query {
int left, right, mx, hp, idx, lca, bucket;
Query() {}
Query(int left, int right, int mx, int hp, int idx, int lca): left(left), right(right), mx(mx), hp(hp), idx(idx), lca(lca), bucket(left / kB) {}
bool operator < (const Query &oth) const {
if(mx == oth.mx) {
if(bucket == oth.bucket) {
if(bucket & 1) {
return right > oth.right;
}
return right < oth.right;
}
return bucket < oth.bucket;
}
return mx < oth.mx;
}
};
vector<Query> Qs;
vector<bool> ans;
struct subsetSum {
struct bol {
uint32_t v1;
uint64_t v2;
// __uint128_t v3;
bol() {}
bol(uint32_t v1, uint64_t v2/*, __uint128_t v3*/): v1(v1), v2(v2)/*, v3(v3)*/ {}
bol& operator += (const bol &addValue) {
v1 += addValue.v1;
v2 += addValue.v2;
// v3 += addValue.v3;
return *this;
}
bol& operator += (const uint64_t &addValue) {
v1 += addValue;
v2 += addValue;
// v3 += addValue;
return *this;
}
bol& operator -= (const uint64_t &subValue) {
v1 -= subValue;
v2 -= subValue;
// v3 -= subValue;
return *this;
}
bol& operator -= (const bol &subValue) {
v1 -= subValue.v1;
v2 -= subValue.v2;
// v3 -= subValue.v3;
return *this;
}
bool operator == (bool cond) const {
return (v1 || v2/* || v3*/) == cond;
}
bool operator ! () const {
return !(v1 || v2/* || v3*/);
}
};
int n;
vector<bol> dp;
subsetSum() {}
subsetSum(int n): n(n), dp(n) {
// printf("subsetSum dp(%d);\n", n);
init();
}
void init() {
dp[0] = bol(1, 1);
for(int i = 1; i < n; i++) {
dp[i] = bol(0, 0);
}
}
void insert(int weight) {
// printf("dp.insert(%d);\n", weight);
for(int i = n - 1; i >= weight; i--) {
dp[i] += dp[i - weight];
}
}
void erase(int weight) {
// printf("dp.erase(%d);\n", weight);
for(int i = weight; i < n; i++) {
dp[i] -= dp[i - weight];
}
}
bool query(int weight) {
// printf("cout << dp.query(%d) << '\\n';\n", weight);
return dp[weight] == 1;
}
bool operator [] (int weight) {
return query(weight);
}
};
subsetSum dp;
vector<bool> marked;
int frq[kV + 1], to_update[kV + 1];
void add(int u) {
if(marked[u] == 0) {
frq[weight[u]]++;
to_update[weight[u]]++;
marked[u] = 1;
} else {
frq[weight[u]]--;
to_update[weight[u]]--;
marked[u] = 0;
}
}
void updateAll(int mx) {
for(int i = 1; i < mx; i++) {
if(to_update[i] < 0) {
to_update[i] = -to_update[i];
while(to_update[i]) {
to_update[i]--;
dp.erase(i);
}
} else {
while(to_update[i]) {
to_update[i]--;
dp.insert(i);
}
}
}
}
void updateOne(int i) {
int cnt = 1;
if(to_update[i] < 0) {
to_update[i] = -to_update[i];
while(to_update[i]) {
to_update[i]--;
dp.erase(i);
}
} else {
while(to_update[i]) {
to_update[i]--;
dp.insert(i);
}
}
}
int main() {
fin.tie(nullptr)->sync_with_stdio(false);
int n;
assert(fin >> n);
assert(2 <= n && n <= kN);
for(int i = 0; i < n; i++) {
assert(fin >> weight[i]);
assert(1 <= weight[i] && weight[i] <= kV);
}
for(int i = 1; i < n; i++) {
int u, v;
assert(fin >> u >> v);
assert(1 <= u && u <= n);
assert(1 <= v && v <= n);
u--; v--;
adj[u].emplace_back(v);
adj[v].emplace_back(u);
}
dfs();
int q;
assert(fin >> q);
assert(1 <= q && q <= kQ);
ans = vector<bool>(q);
for(int i = 0; i < q; i++) {
int u, v, hp;
assert(fin >> u >> v >> hp);
assert(1 <= u && u <= n);
assert(1 <= v && v <= n);
assert(0 <= hp && hp <= kV);
u--; v--;
if(tin[u] > tin[v]) {
swap(u, v);
}
int lca = lcaQuery(u, v), mx = maxChain(u, v);
if(lca == u) {
Qs.emplace_back(tin[u], tin[v], mx, hp, i, -1);
} else {
Qs.emplace_back(tout[u], tin[v], mx, hp, i, lca);
}
}
sort(Qs.begin(), Qs.end());
dp = subsetSum(kS + 1);
int lst = -1, l, r;
for(int i = 0; i < q; i++) {
int left = Qs[i].left;
int right = Qs[i].right;
int mx = Qs[i].mx;
int hp = Qs[i].hp;
int lca = Qs[i].lca;
if(mx != lst) {
memset(to_update, 0, sizeof(to_update));
memset(frq, 0, sizeof(frq));
marked = vector<bool>(n);
dp.init();
l = left;
r = right;
for(int j = l; j <= r; j++) {
add(plusminus[j]);
}
} else {
while(l < left) {
add(plusminus[l]); // rem
l++;
}
while(l > left) {
l--;
add(plusminus[l]);
}
while(r < right) {
r++;
add(plusminus[r]);
}
while(r > right) {
add(plusminus[r]); // rem
r--;
}
}
if(lca != -1) {
add(lca);
}
updateAll(mx);
int frq_mx = frq[mx];
bool crt_ans = 0;
for(int cnt = 0; crt_ans == 0 && cnt <= frq_mx && cnt * mx <= hp; cnt++) {
int crt_hp = hp - cnt * mx, crt_frq = frq_mx - cnt;
if(crt_frq & 1) {
if(crt_hp >= mx && dp[crt_hp - mx]) {
crt_ans = 1;
}
} else if(dp[crt_hp]){
crt_ans = 1;
}
}
ans[Qs[i].idx] = crt_ans;
if(lca != -1) {
add(lca); // rem
if(weight[lca] != mx) {
updateOne(weight[lca]);
}
}
to_update[mx] = 0;
lst = mx;
}
for(int i = 0; i < q; i++) {
YN(ans[i]);
}
return 0;
}

View File

@@ -0,0 +1,122 @@
#include <bits/stdc++.h>
using namespace std;
#ifdef LOCAL
ifstream fin("brute.in");
ofstream fout("brute.out");
#else
#define fin cin
#define fout cout
#endif
void YN(bool cond) {
if(cond) {
fout << "YES\n";
} else {
fout << "NO\n";
}
}
const int kV = 1000;
const int kQ = 1e4;
const int kN = 1e4;
const int kS = 1000;
vector<int> depth, parent, weight;
vector<vector<int>> adj;
void dfs(int u = 0, int v = -1) {
for(const auto &it: adj[u]) if(it != v) {
depth[it] = depth[u] + 1;
parent[it] = u;
dfs(it, u);
}
}
bool check_greedy(const vector<int> &h, int hp) {
bitset<kS + 1> dp;
dp[0] = 1;
int mx = 0, frq = 1;
for(const auto &it: h) {
if(it > mx) {
mx = it;
frq = 1;
} else if(it == mx) {
frq++;
}
}
for(const auto &it: h) {
if(it != mx && it <= hp) {
dp |= dp << it;
}
}
for(int i = 0; i <= frq; i++) {
if(i * mx > hp) {
return 0;
}
int crt_hp = hp - i * mx, crt_frq = frq - i;
if(crt_frq & 1) {
if(crt_hp >= mx && dp[crt_hp - mx]) {
return 1;
}
} else {
if(dp[crt_hp]) {
return 1;
}
}
}
return 0;
}
int main() {
int n;
fin >> n;
adj = vector<vector<int>>(n);
weight = vector<int>(n);
for(auto &it: weight) {
fin >> it;
}
for(int i = 1; i < n; i++) {
int u, v;
fin >> u >> v;
u--; v--;
adj[u].emplace_back(v);
adj[v].emplace_back(u);
}
depth = vector<int>(n);
parent = vector<int>(n);
dfs();
int q;
fin >> q;
for(int i = 0; i < q; i++) {
int u, v, hp;
fin >> u >> v >> hp;
u--; v--;
vector<int> h;
if(depth[u] < depth[v]) {
swap(u, v);
}
while(depth[u] > depth[v]) {
h.emplace_back(weight[u]);
u = parent[u];
}
while(u != v) {
h.emplace_back(weight[u]);
h.emplace_back(weight[v]);
u = parent[u];
v = parent[v];
}
h.emplace_back(weight[u]);
bool ans = check_greedy(h, hp);
YN(ans);
}
return 0;
}

BIN
2023/rcpc/d2/statements.pdf Normal file

Binary file not shown.