训练合集-Mind the Gap
训练合集-Mind the Gap
Member :EdGrass afeng111 xishuiw
wirtten by xishuiw
- 训练合集-Mind the Gap
- 2023暑期训练前半
- 0.2022-2023 ACM-ICPC Latin American Regional Programming Contest
- 1.The 2022 ICPC Asia Nanjing Regional Contest
- 2.2019-2020 ICPC Asia Hong Kong Regional Contest
- 3.The 2021 ICPC Asia Nanjing Regional Contest (XXII Open Cup, Grand Prix of Nanjing)
- 4.2020-2021 ACM-ICPC, Asia Nanjing Regional Contest (XXI Open Cup, Grand Prix of Nanjing)
- 5.2022 ICPC Southeastern Europe Regional Contest
- 6.The 15th Chinese Northeast Collegiate Programming Contest
- 7.2021 Jiangxi Provincial Collegiate Programming Contest
- 8.2019-2020 ACM-ICPC Pacific Northwest Regional Contest (Div. 1)
- 9.The 13th Chinese Northeast Collegiate Programming Contest
- 10.The 10th Shandong Provincial Collegiate Programming Contest
- 2023暑期训练后半
- 1. 2023 Xian Jiaotong University Programming Contest
- 2. 2019-2020 ACM-ICPC Brazil Subregional Programming Contest
- 3. 2019 ICPC Universidad Nacional de Colombia Programming
- 4. 2018-2019 9th BSUIR Open Programming Championship
- 5. 2019-2020 Winter Petrozavodsk Camp, Day 8: Almost Algorithmic Contest
- 6. 2020-2021 ACM-ICPC Brazil Subregional Programming Contest
- 7. 2018-2019 ACM-ICPC Brazil Subregional Programming Contest
- 8. 2020-2021 Winter Petrozavodsk Camp, Day 5: Almost Retired Dandelion Contest (XXI Open Cup, Grand Prix of Nizhny Novgorod)
- 2023暑期训练前半
2023暑期训练前半
0.2022-2023 ACM-ICPC Latin American Regional Programming Contest
赛时过题 DEILM
补题ACH
D.Daily Trips
签到 问什么时候需要带伞
#include<bits/stdc++.h>
#define close std::ios::sync_with_stdio(false),cin.tie(0),cout.tie(0)
using namespace std;
typedef long long ll;
const ll MAXN = 3e5+7;
const ll mod = 1e9+7;
const ll inf = 0x3f3f3f3f;
void solve(){
int n,a,b;cin>>n>>a>>b;
for(int i=1;i<=n;i++){
char ch1,ch2;
cin>>ch1>>ch2;
if(ch1=='Y'||b==0){
cout<<"Y ";
a--;
b++;
}
else {
cout<<"N ";
}
if(ch2=='Y'||a==0){
cout<<"Y ";
b--;
a++;
}
else {
cout<<"N ";
}
cout<<"\n";
}
}
signed main(){
close;
solve();
}
E.Empty Square
#include <iostream>
using namespace std;
const int N = 1007;
int vis[N];
int main()
{
std::ios::sync_with_stdio(false);
cin.tie(0);
cout.tie(0);
int n, k, e;
cin >> n >> k >> e;
vis[k] = 1;
int l = e, r = n - k - e;
int ans = 0;
if (l > r)
swap(l, r);
if (l == 1)
{
if (vis[1])
ans++;
else
vis[1] = 1;
}
else if (l == 2)
{
if (vis[2])
{
vis[1] = 1;
ans++;
}
else
vis[2] = 1;
}
else if (l == 3)
{
if (vis[3])
{
vis[1] = vis[2] = 1;
}
else
{
vis[3] = 1;
}
}
else if (l == 4)
{
if (vis[4] == 1)
{
vis[1] = 1;
vis[3] = 1;
}
else
{
vis[4] = 1;
}
}
if (r == 1)
{
if (vis[1])
ans++;
}
else if (r == 2)
{
if (vis[2])
{
if (vis[1])
ans += 2;
else
ans++;
}
}
else if (r == 3)
{
if (vis[3])
{
if (vis[2])
{
if (vis[1])
{
ans += 3;
}
else
ans += 2;
}
else
{
if (vis[1])
{
ans += 1;
}
}
}
}
else if (r == 4)
{
if (vis[4] == 1)
{
if (vis[3])
{
if (vis[2])
{
if (vis[1])
ans += 4;
else
ans += 3;
}
else
{
if (vis[1])
ans += 2;
else
ans++;
}
}
else
{
if (vis[1])
ans++;
}
}
}
cout << ans << endl;
}
I. Italian Calzone & Pasta Corner
找一个最大上升子序列 路径里 图很小 对每个点跑bfs 注意剪枝
#include<bits/stdc++.h>
#define close std::ios::sync_with_stdio(false),cin.tie(0),cout.tie(0)
using namespace std;
typedef long long ll;
const ll MAXN = 3e5+7;
const ll mod = 1e9+7;
const ll inf = 0x3f3f3f3f;
int mp[300][300];
int vis[300][300],f[300][300];
int fx[4][2]={1,0,-1,0,0,1,0,-1};
void solve(){
int n,m;cin>>n>>m;
for(int i=1;i<=n;i++){
for(int j=1;j<=m;j++) cin>>mp[i][j];
}
int ans=0;
for(int i=1;i<=n;i++){
for(int j=1;j<=m;j++){
int res=0;
if(vis[i][j]) continue;
for(int x=1;x<=n;x++){
for(int y=1;y<=m;y++) f[x][y]=0;
}
queue<array<int,2>> que;
que.push({i,j});
f[i][j]=1;
vis[i][j]=1;
res=1;
while(que.size()){
int x=que.front()[0],y=que.front()[1];
que.pop();
for(int v=0;v<4;v++){
int xx=x+fx[v][0],yy=y+fx[v][1];
if(xx<1||xx>n||yy<1||yy>m||f[xx][yy]||mp[x][y]>mp[xx][yy]) continue;
f[xx][yy]=1;res++;
vis[xx][yy]=1;
que.push({xx,yy});
}
}
ans=max(ans,res);
}
}
cout<<ans<<"\n";
}
signed main(){
close;
solve();
}
L. Lazy Printing
给打印机 找长度在限制范围内的最小的模板串数量
贪心地不停向后枚举 然后用hash优化下过了 但是这个还是n2的 数据太弱 标准做法kmp
#include <bits/stdc++.h>
#define close \
std::ios::sync_with_stdio(false); \
cin.tie(0); \
cout.tie(0)
using namespace std;
typedef unsigned long long ULL;
const int N = 1007;
const int MANX = 4e5+7;
int n, d,P=131;
char s[200010];
const int inf = 2e9;
ULL h[MANX], p[MANX];
ULL get(int l, int r) {
return h[r] - h[l - 1] * p[r - l + 1];
}
inline int find(int now, int i) {
// int pos = now;
int t = 0;
int ans=now;
int pos=now;
pos+=i;
ULL k=get(now,pos);
while(pos<=n){
ULL tmp=get(pos-i,pos);
if(tmp!=k) break;
ans=pos;
pos+=i;
}
pos=now;
while (s[pos] == s[ans]) {
++pos;
++ans;
++t;
if (t == i) {
t = 0;
pos = now;
}
}
return ans;
}
int main() {
close;
p[0] = 1;
cin >> s+1 >> d;
n = strlen(s+1);
for (int i = 1; i <= n; i ++ ) {
h[i] = h[i - 1] * P + s[i];
p[i] = p[i - 1] * P;
}
int now = 1;
int ans = 0;
while (now <= n) {
int mx = 0;
for (int i = 1; i <= d; ++i) {
int k = find(now, i);
if (k > mx) {
mx = k;
}
}
++ans;
now = mx;
}
cout << ans;
}
M. Maze in Bolt
可以旋转的锁 一步一步转看看能不能下去 并且可以换头的方向
队友搓的搜索 很牛
#include <iostream>
#include <queue>
using namespace std;
const int N = 1007;
char mp[N][N];
int row, col;
int flag[N][N];
int vis[N][N];
char tag[N];
int bg = -1;
int dx[4] = {0, 0, 1, -1};
int dy[4] = {1, -1, 0, 0};
bool check(int r, int c)
{
for (int i = 0; i < col; i++)
{
if (tag[(bg + i) % col] == '0')
continue;
if (mp[r][(c + i) % col] == '1')
return false;
}
return true;
}
bool bfs()
{
for (int i = 1; i <= row; i++)
{
for (int j = 0; j < col; j++)
{
if (check(i, j))
flag[i][j] = 1;
else
flag[i][j] = 0;
vis[i][j] = 0;
// if (flag[i][j])
// cout << i << ' ' << j + 1 << endl;
}
}
queue<pair<int, int>> q;
bool getans = false;
for (int i = 0; i < col; i++)
{
if (flag[1][i])
{
vis[1][i] = 1;
q.push({1, i});
}
}
while (q.size())
{
int x = q.front().first, y = q.front().second;
q.pop();
if (x == row)
{
getans = true;
break;
}
for (int i = 0; i < 4; i++)
{
int xx = x + dx[i];
int yy = (y + dy[i] + col) % col;
if (xx <= 0 || xx > row)
continue;
if (vis[xx][yy])
continue;
if (flag[xx][yy] == 0)
continue;
vis[xx][yy] = 1;
q.push({xx, yy});
}
}
return getans;
}
int main()
{
std::ios::sync_with_stdio(false);
cin.tie(0);
cout.tie(0);
cin >> row >> col;
for (int i = 0; i < col; i++)
{
cin >> tag[i];
// cout << tag[i];
if (tag[i] == '1' && bg == -1)
bg = i;
}
// cout << endl;
// cout << bg << endl;
for (int i = 1; i <= row; i++)
{
for (int j = 0; j < col; j++)
{
cin >> mp[i][j];
}
}
if (bg == -1)
{
cout << "Y";
return 0;
}
if (bfs())
cout << "Y";
else
{
for (int i = 0; i < col - i - 1; i++)
{
// cout << i << ' ' << col - i << endl;
swap(tag[i], tag[col - i - 1]);
}
for (int i = 0; i < col; i++)
{
// cout << tag[i];
if (tag[i] == '1')
{
bg = i;
break;
}
}
// cout << endl;
if (bfs())
cout << "Y";
else
cout << "N" << endl;
}
}
A. Asking for Money
每个人被一个人要钱时候可以对两个人要钱
随机某个人被要1元 问谁最后有可能不亏钱
不亏钱条件是有一个点能同时到达三个点
建反图 三个点同时到达一个点 复杂度大大优化
#include<bits/stdc++.h>
#define close std::ios::sync_with_stdio(false),cin.tie(0),cout.tie(0)
using namespace std;
typedef long long ll;
const ll MAXN = 3e5+7;
const ll mod = 1e9+7;
const ll inf = 0x3f3f3f3f;
vector<int> adj[MAXN];
pair<int,int> e[MAXN];
int vis[MAXN],tmp[MAXN];
void solve(){
int n;cin>>n;
for(int i=1;i<=n;i++){
int u,v;cin>>u>>v;
adj[u].push_back(i);
adj[v].push_back(i);
e[i]={u,v};
}
for(int i=1;i<=n;i++){
for(int it=1;it<=n;it++) vis[it]=0,tmp[it]=0;
queue<int>que;
que.push(i);
vis[i]=1;
while(que.size()){
int x=que.front();
que.pop();
for(auto &v:adj[x]){
if(!vis[v]){
vis[v]=1;
que.push(v);
}
}
}
for(int j=1;j<=n;j++) if(vis[j]) tmp[j]++;
//
for(int it=1;it<=n;it++) vis[it]=0;
que.push(e[i].first);
vis[e[i].first]=1;
while(que.size()){
int x=que.front();
que.pop();
for(auto &v:adj[x]){
if(v==i) continue;
if(!vis[v]){
vis[v]=1;
que.push(v);
}
}
}
for(int j=1;j<=n;j++) if(vis[j]) tmp[j]++;
//
for(int it=1;it<=n;it++) vis[it]=0;
que.push(e[i].second);
vis[e[i].second]=1;
while(que.size()){
int x=que.front();
que.pop();
for(auto &v:adj[x]){
if(v==i) continue;
if(!vis[v]){
vis[v]=1;
que.push(v);
}
}
}
for(int j=1;j<=n;j++) if(vis[j]) tmp[j]++;
int flag=0;
for(int j=1;j<=n;j++){
if(tmp[j]==3) flag=1;
}
if(flag) cout<<"Y";
else cout<<"N";
}
}
signed main(){
solve();
}
C. City Folding
码力太弱 推不出公式
#include<bits/stdc++.h>
#define close std::ios::sync_with_stdio(false),cin.tie(0),cout.tie(0)
using namespace std;
typedef long long ll;
const ll MAXN = 3e5+7;
const ll mod = 1e9+7;
const ll inf = 0x3f3f3f3f;
#define int ll
int f[MAXN];
vector<int> ans;
void solve(){
int n,p,h;cin>>n>>p>>h;
p--;h--;
for(int i=n-1;i>=0;i--){
if(h>=(1LL<<i)) {
f[n-i-1]=1;
h=(1LL<<(i+1))-1-h;
}
//cout<<"# h = "<<h<<" "<<f[n-i-1]<<"\n";
}
//预处理是否需要翻动来增加高度,f为1表示需要增加一次高度
//3 8 3 第一次翻动增加4 不需要 第二次翻动增加2 需要,翻动后长度变为剩下的长度
for(int i=n-1;i>=0;i--){
//第i次翻动 h改变的是1<<(n-i-1) p改变的是1<<i
if(!f[i]){
// cout<<f[i];//需要增加h
if(p<(1LL<<i)){
cout<<"R";
}
else{
cout<<"L";
p-=(1LL<<i);
}
}
else{//需要的长度大
// cout<<f[i];
//反转后高度会改变
if(p<(1LL<<i)){
cout<<"L";
p=(1LL<<i)-1-p;
}
else{
cout<<"R";
p=(1LL<<(i+1))-1-p;
}
}
}
}
signed main(){
solve();
}
1.The 2022 ICPC Asia Nanjing Regional Contest
赛时过题AGIM 补题D
A. Stop, Yesterday Please No More
有很多袋鼠 满的 然后会根据题目给的走 问有几种放洞的方法 可以让最后剩下k个袋鼠
我一开始在走洞 写了一个自己样例都过不去的做法
队友上机敲了一发走袋鼠的 直接过了
#include <iostream>
#include <vector>
#include <queue>
#include <algorithm>
#include <string>
#include <stack>
#include <iomanip>
// 小数位 cout<<fixed<<setprecision(12)<<dis[n+1]<<endl;
using namespace std;
#define close \
std::ios::sync_with_stdio(false); \
cin.tie(0); \
cout.tie(0)
const int N = 1e3 + 7;
typedef long long ll;
int row, col, lv;
string s;
ll vis[N][N];
ll count(int x1, int y1, int x2, int y2)
{
// cout << vis[x2][y2] << " " << vis[x1 - 1][y1 - 1] << ' ' << vis[x1 - 1][y2] << ' ' << vis[x2][y1 - 1] << endl;
return vis[x2][y2] + vis[x1 - 1][y1 - 1] - vis[x1 - 1][y2] - vis[x2][y1 - 1];
}
void solve()
{
cin >> row >> col >> lv;
for (int i = 1; i <= row; i++)
for (int j = 1; j <= col; j++)
vis[i][j] = 0;
cin >> s;
ll v = 0, h = 0; // 竖直,水平
ll mxv0, mxv1, mxh0, mxh1;
mxv0 = mxv1 = mxh0 = mxh1 = 0;
ll x = 1, y = 1;
for (int i = 0; i < s.length(); i++)
{
if (s[i] == 'U')
{
v++;
x = max(x, v + 1);
mxv0 = max(mxv0, v);
}
else if (s[i] == 'D')
{
v--;
mxv1 = min(mxv1, v);
}
else if (s[i] == 'L')
{
h--;
y = max(y, -h + 1);
mxh1 = min(mxh1, h);
}
else
{
h++;
mxh0 = max(mxh0, h);
}
}
ll szrow = row - mxv0 + mxv1, szcol = col - mxh0 + mxh1;
if (szrow <= 0 || szcol <= 0)
{
if (lv == 0)
cout << row * col << endl;
else
cout << 0 << endl;
return;
}
// cout << szrow << ' ' << szcol << endl;
// cout << x << ' ' << y << endl;
vis[x][y] = 1;
for (int i = 0; i < s.length(); i++)
{
if (s[i] == 'U')
{
x--;
}
else if (s[i] == 'D')
{
x++;
}
else if (s[i] == 'L')
{
y--;
}
else
{
y++;
}
vis[x][y] = 1;
}
for (int i = 1; i <= row; i++)
{
for (int j = 1; j <= col; j++)
{
vis[i][j] += -vis[i - 1][j - 1] + vis[i - 1][j] + vis[i][j - 1];
}
}
// for (int i = 1; i <= row; i++)
// {
// for (int j = 1; j <= col; j++)
// {
// cout << vis[i][j] << ' ';
// }
// cout << endl;
// }
ll ans = 0;
// cout << count(2, 2, 3, 3) << endl;
ll sz = szrow * szcol;
// for (int i = szrow; i <= row; i++)
// {
// for (int j = szcol; j <= col; j++)
// {
// ll cnt = count(i - szrow + 1, j - szcol + 1, i, j);
// if (cnt + lv == sz)
// ans++;
// }
// }
// cout << ans << ' ';
// ans = 0;
for (int i = 1; i <= row; i++)
{
for (int j = 1; j <= col; j++)
{
ll cnt = count(max(1ll, i - szrow + 1), max(1ll, j - szcol + 1), i, j);
if (cnt + lv == sz)
ans++;
}
}
cout << ans << endl;
}
int main()
{
close;
int t = 1;
cin >> t;
while (t--)
{
solve();
}
}
G. Inscryption
野兽合并 写太急了被我wa了一发
显然是合并越多越好 0可以变成1 所以是类似反悔贪心
0多了就把1个0变1
#include<bits/stdc++.h>
#define close std::ios::sync_with_stdio(false),cin.tie(0),cout.tie(0)
using namespace std;
typedef long long ll;
#define int ll
const ll MAXN = 1e6+7;
const ll mod = 1e9+7;
const ll inf = 0x3f3f3f3f;
int a[MAXN];
void solve(){
int n;cin>>n;
int cnt0=0,cnt1=0,cnt2=0;
int now=0;
int flag=1;
for(int i=1;i<=n;i++){
cin>>a[i];
if(a[i]==0) cnt0++;
else if(a[i]==1) cnt1++;
else cnt2++;
if(a[i]!=0)
now+=a[i];
else now-=1;
if(now<0){
if(cnt0){
cnt0--;
cnt1++;
now+=2;
}
else flag=0;
}
}
int fz=1+cnt1,fm=1+cnt1-cnt0-cnt2;
if(!flag) cout<<"-1\n";
else{
int tmp=__gcd(fz,fm);
cout<<fz/tmp<<" "<<fm/tmp<<"\n";
}
}
signed main(){
close;
int t;cin>>t;
while(t--)
solve();
}
I. Perfect Palindrome
结论:全变成一样的
#include<bits/stdc++.h>
#define ll long long
#define PII pair<int,int>
// #define int long long
using namespace std;
constexpr ll mod=1e9+7;
const ll inf=0x3f3f3f3f;
const ll INF=0x3f3f3f3f3f3f3f3f;
const double eps=1e-10;
const int N=2e5+10;
// struct node{
// friend bool operator<(const node&a,const node&b){
// return ;
// }
// }
//priority_queue<ll,vector<ll>,greater<ll>>pq;
inline int read(){int x=0,f=1;char ch=getchar();while(ch<'0'||ch>'9'){if(ch=='-')f=-1;ch=getchar();}while(ch>='0'&&ch<='9'){x=(x<<1)+(x<<3)+(ch^48);ch=getchar();}return x*f;}
inline void write(int x){char F[200];int tmp=x>0?x:-x;if(x<0) putchar('-');int cnt=0;while(tmp>0){F[cnt++]=tmp%10+'0';tmp/=10;}while(cnt>0)putchar(F[--cnt]);}
inline int combination(int n,int k){int sum=0;if (n==k||k==0){return 1;}else{return combination(n-1,k)+combination(n-1,k-1);}}
map<char,int>mp;
void solve(){
// int n=read();
string s;
mp.clear();
cin>>s;
for(int i=0;i<s.size();i++){
mp[s[i]]++;
}
int maxx=-1;
for(auto it:mp){
int y=it.second;
maxx=max(y,maxx);
}
cout<<s.size()-maxx<<'\n';
//puts(ans>0?"YES":"NO");
//puts(ans>0?"Yes":"No");
}
signed main(){
// ios::sync_with_stdio(false);
// cin.tie(0);
// cout.tie(0);
// int t=1;
int t=read();
while(t--){
solve();
}
}
M. Drain the Water Tank
队友写的 向量判上边和下边 因为给定顺序排过了 所以就看看是不是下凹和下平
#include <iostream>
#include <vector>
#include <queue>
#include <algorithm>
#include <string>
#include <stack>
#include <iomanip>
// 小数位 cout<<fixed<<setprecision(12)<<dis[n+1]<<endl;
using namespace std;
#define close \
std::ios::sync_with_stdio(false); \
cin.tie(0); \
cout.tie(0)
const int N = 2e5 + 7;
const int inf = 2e9;
struct node
{
int x, y;
} nd[N];
int n;
void solve()
{
cin >> n;
int mn = inf, index = 0;
for (int i = 0; i < n; i++)
cin >> nd[i].x >> nd[i].y;
int ans = 0;
for (int i = 0; i < n; i++)
{
int x = nd[i].x, y = nd[i].y;
int nx = (i + 1) % n;
int xx = nd[nx].x, yy = nd[nx].y;
int nxx = (nx + 1) % n;
int xxx = nd[nxx].x, yyy = nd[nxx].y;
if (x < xx && y > yy)
{
if (yyy > yy && (xxx >= xx || (yyy - yy) * (x - xx) < (y - yy) * (xxx - xx)))
ans++;
}
else if (x == xx && y > yy)
{
if (yyy > yy && xxx > xx)
ans++;
}
else if (x > xx && y > yy)
{
if (yyy > yy && xxx > xx && (yyy - yy) * (x - xx) < (y - yy) * (xxx - xx))
ans++;
}
}
// cout << ans << endl;
for (int i = 0; i < n; i++)
{
int nx = (i + 1) % n;
while (nd[i].y == nd[nx].y && nd[i].x < nd[nx].x)
nx = (nx + 1) % n;
if (nx == (i + 1) % n)
continue;
int pre = (n + i - 1) % n;
if (nd[pre].y > nd[i].y && nd[(n + nx - 1) % n].y < nd[nx].y)
ans++;
}
cout << ans << endl;
}
int main()
{
close;
int t = 1;
// cin >> t;
while (t--)
{
solve();
}
}
D. Chat Program
一次可以加一个等差数列 问第k大的数最多是多大
二分答案 看看加上后>=mid的数是否大于k个
#include<bits/stdc++.h>
#define close std::ios::sync_with_stdio(false),cin.tie(0),cout.tie(0)
using namespace std;
typedef long long ll;
const ll MAXN = 3e5+7;
const ll mod = 1e9+7;
const ll inf = 0x3f3f3f3f;
const ll INF = 0x3f3f3f3f3f3f3f3f;
#define int ll
int n,k,m,c,d;
int a[MAXN],pre[MAXN];
bool check(int mid){
int cnt=0;
for(int i=1;i<=n;i++) pre[i]=0;
for(int i=1;i<=n;i++){
if(a[i]>=mid) cnt++;
else{
int tmp=mid-a[i];
tmp-=c;
int pos;
if(tmp<=0) {
pos=max(i-m+1,1LL);
pre[pos]++;
pre[i+1]--;
}
else{
int p;
if(d==0){
continue;
}
p=tmp/d;
if(p*d!=tmp) p++;
if(p>m) continue;
pos=i-p;
if(pos<1) continue;
p=max(i-m+1,1LL);
pre[p]++;
pre[min(pos+1,i+1)]--;
}
}
}
pre[1]+=cnt;
for(int i=1;i<=n;i++){
pre[i]=pre[i]+pre[i-1];
if(pre[i]>=k) return true;
}
return false;
}
void solve(){
cin>>n>>k>>m>>c>>d;
for(int i=1;i<=n;i++) cin>>a[i];
int l=0,r=INF;
while(l<=r){
int mid=l+r>>1;
if(check(mid)){
l=mid+1;
}
else{
r=mid-1;
}
}
cout<<r;
}
signed main(){
close;
solve();
}
2.2019-2020 ICPC Asia Hong Kong Regional Contest
赛时过题BDG 补题EJ
B. Binary Tree
每次拿不改变奇偶性 算树的总大小就行了
#include<bits/stdc++.h>
#define close std::ios::sync_with_stdio(false),cin.tie(0),cout.tie(0)
using namespace std;
typedef long long ll;
const ll MAXN = 3e5+7;
const ll mod = 1e9+7;
const ll inf = 0x3f3f3f3f;
void solve(){
int n;cin>>n;
for(int i=1;i<n;i++){
int u,v;cin>>u>>v;
}
if(n%2==1) cout<<"Alice\n";
else cout<<"Bob\n";
}
signed main(){
close;
int t;cin>>t;
while(t--)
solve();
}
D. Defining Labels
类似进制转换 队友写的
#include <iostream>
#include <vector>
#include <stack>
#include <map>
#include <queue>
#include <string>
#include <algorithm>
#include <iomanip> //fixed<<setprecision(12)<<
#include <utility> //pair模板
#include <cmath>
#include <random> //mt19937 mtrand(time(0));
#include <time.h>
#define close \
std::ios::sync_with_stdio(false); \
cin.tie(0); \
cout.tie(0)
typedef long long ll;
typedef unsigned long long ull;
const int N = 2e5 + 2;
const ll mod = 200907;
using namespace std;
int k, x;
void solve()
{
// freopen("data.in.txt","r",stdin);
// freopen("data.out.txt","w",stdout);
cin >> k >> x;
int d = 9 - (10 - k) + 1;
// cout << d << endl;
vector<int> ans;
while (x > 0)
{
ans.push_back((x - 1) % d + (10 - k));
// cout << (x - 1) % d + (10 - k);
// x = (x - 1) / d + 1;
x = (x / d) - (int)(x % d == 0);
}
for (int i = ans.size() - 1; i >= 0; i--)
cout << ans[i];
cout << endl;
}
int main()
{
close;
int t = 1;
cin >> t;
while (t--)
{
solve();
}
return 0;
}
G. Game Design
#include <iostream>
#include <vector>
#include <stack>
#include <map>
#include <queue>
#include <string>
#include <algorithm>
#include <iomanip> //fixed<<setprecision(12)<<
#include <utility> //pair模板
#include <cmath>
#include <random> //mt19937 mtrand(time(0));
#include <time.h>
#define close \
std::ios::sync_with_stdio(false); \
cin.tie(0); \
cout.tie(0)
typedef long long ll;
typedef unsigned long long ull;
const int N = 2e5 + 2;
const ll mod = 200907;
using namespace std;
int k, cnt;
map<int, int> wei, fa;
void dfs(int k, int f)
{
cnt++;
// cout << cnt << ' ' << f << endl;
fa[cnt] = f;
int tp = cnt;
if (k == 1)
{
wei[tp] = 1;
wei[f] += wei[tp];
return;
}
k--;
if (k % 2 == 0)
{
// cout << cnt << endl;
dfs(2, tp);
dfs(k / 2, tp);
}
else
{
dfs(k, cnt);
}
wei[f] += wei[tp];
}
void solve()
{
// freopen("data.in.txt","r",stdin);
// freopen("data.out.txt","w",stdout);
cin >> k;
if (k == 1)
{
cout << 2 << endl;
cout << 1 << endl;
cout << 1 << ' ' << 2 << endl;
return;
}
// cout << k << endl;
dfs(k, 0);
cout << cnt << endl;
for (int i = 2; i <= cnt; i++)
cout << fa[i] << ' ';
cout << endl;
for (int i = 1; i <= cnt; i++)
cout << wei[i] << ' ';
cout << endl;
}
int main()
{
close;
int t = 1;
// cin >> t;
while (t--)
{
solve();
}
return 0;
}
E. Erasing Number
能处于中位数的肯定能删
三个连续大数能变成两个的 对于每个数 数连续的大数n2去做
J. Junior Mathematician
数位dp 模板题 赛场看出来了不会写
#include<bits/stdc++.h>
#define close std::ios::sync_with_stdio(false),cin.tie(0),cout.tie(0)
using namespace std;
typedef long long ll;
const ll MAXN = 1e4+7;
const ll mod = 1e9+7;
const ll inf = 0x3f3f3f3f;
ll dp[MAXN][62][62];//pos pre 贡献
// dp[i][j][m]
//轮流枚举每一位的情况 都可以由上一位推出 复杂度为O(10n)
//pre表示前缀和 来算此时数的大小
//第三维记录f[x]-x
//f[x] 增加了 pre*x, x增加了x*1-^n
//贡献=贡献-x*10^n+pre*x
int p[MAXN],upper[MAXN],m;
void init(int x) {
p[1]=1;
for(int i=2; i<=x+1; i++) {
p[i]=p[i-1]*10;
p[i]%=m;
}
}
ll dfs(int pos,int pre_num,int c,int flag) {
int max_number;
if(pos<=0) return c==0;
if(!flag&&dp[pos][pre_num][c]!=-1) return dp[pos][pre_num][c];
if(flag) max_number=upper[pos];
else max_number=9;
ll ret=0;
for(int i=0; i<=max_number; i++) {
//转移方程
ret+=dfs(pos-1,(i+pre_num)%m,((c-i*p[pos]+pre_num*i)%m+m)%m,flag&&(i==max_number));
ret=(ret+mod)%mod;
}
ret=(ret+mod)%mod;
if(!flag) dp[pos][pre_num][c]=ret;
return ret;
}
void solve() {
string a,b;
cin>>a>>b>>m;
int l=max(a.length(),b.length());
init(l);
int len=a.length();
a[len-1]--;
for(int i=0; i<=l+4; i++) {
for(int j=0; j<=m; j++) {
for(int x=0; x<=m; x++) {
dp[i][j][x]=-1;
}
}
}
for(int i=len-1; i>=0; i--) {
if(a[i]>='0'&&a[i]<='9') break;
a[i]='9',a[i-1]--;
}
for(int i=0; i<len; i++) {
upper[len-i]=a[i]-'0';
}
//cout<<"## "<<a<<"\n";
ll aa=dfs(len,0,0,1);
for(int i=0; i<=l+4; i++) {
for(int j=0; j<=m; j++) {
for(int x=0; x<=m; x++) {
dp[i][j][x]=-1;
}
}
}
len=b.length();
for(int i=0; i<len; i++) {
upper[len-i]=b[i]-'0';
}
ll bb=dfs(len,0,0,1);
cout<<(bb-aa+mod)%mod<<"\n";
}
signed main() {
close;
int t;cin>>t;
while(t--)
solve();
}
3.The 2021 ICPC Asia Nanjing Regional Contest (XXII Open Cup, Grand Prix of Nanjing)
赛时过题ACHM 补题EJ
A. Oops, It’s Yesterday Twice More
#include <iostream>
#include <vector>
#include <stack>
#include <map>
#include <set>
#include <queue>
#include <string>
#include <algorithm>
#include <iomanip> //fixed<<setprecision(12)<<
#include <utility> //pair模板
#include <cmath>
#include <random> //mt19937 mtrand(time(0));
#include <time.h>
#define close \
std::ios::sync_with_stdio(false); \
cin.tie(0); \
cout.tie(0)
typedef long long ll;
typedef unsigned long long ull;
const int N = 2e5 + 2;
const ll mod = 200907;
using namespace std;
int n, a, b;
void solve()
{
// freopen("data.in.txt","r",stdin);
// freopen("data.out.txt","w",stdout);
cin >> n >> a >> b;
if (a <= n / 2)
{
if (b <= n / 2)
{
for (int i = 1; i < n; i++)
cout << "UL";
for (int i = 1; i < b; i++)
cout << 'R';
for (int i = 1; i < a; i++)
cout << 'D';
}
else
{
for (int i = 1; i < n; i++)
cout << "UR";
for (int i = 1; i < a; i++)
cout << 'D';
for (int i = 1; i <= n - b; i++)
cout << 'L';
}
}
else
{
if (b <= n / 2)
{
for (int i = 1; i < n; i++)
cout << "DL";
for (int i = 1; i < b; i++)
cout << 'R';
for (int i = 1; i <= n - a; i++)
cout << 'U';
}
else
{
for (int i = 1; i < n; i++)
cout << "DR";
for (int i = 1; i <= n - a; i++)
cout << 'U';
for (int i = 1; i <= n - b; i++)
cout << 'L';
}
}
}
int main()
{
close;
int t = 1;
// cin>>t;
while (t--)
{
solve();
}
return 0;
}
C. Klee in Solitary Confinement
对区间+k 找众数最多的情况
由于数的总数不多,因此考虑dp它+或者不+的状态 实时更新最大值
用map会t 于是对每个数+2e6变成数组
#include<bits/stdc++.h>
#define close std::ios::sync_with_stdio(false),cin.tie(0),cout.tie(0)
using namespace std;
typedef long long ll;
const ll MAXN = 1e7+7;
const ll mod = 1e9+7;
const ll inf = 0x3f3f3f3f;
int mp[MAXN],tmp[MAXN],mx[MAXN];
int a[MAXN];
void solve(){
int n,m;
cin>>n>>m;
for(int i=1;i<=n;i++){
cin>>a[i];
a[i]+=2e6;
mp[a[i]]++;
tmp[a[i]+m]++;
tmp[a[i]]--;
if(tmp[a[i]]<0)
tmp[a[i]]=0;
mx[a[i]]=max(tmp[a[i]],mx[a[i]]);
mx[a[i]+m]=max(tmp[a[i]+m],mx[a[i]+m]);
}
int ans=0;
for(int i=1;i<=n;i++){
ans=max(ans,mp[a[i]]+mx[a[i]]);
}
cout<<ans;
}
signed main(){
close;
solve();
}
H. Crystalfly
树dp
在对u点进行dp的时候 有两种情况
第一种是所有v都删除 留个最大的 dp值由v的所有节点推出
第二种是留一个 但是这个节点的子节点贡献不保留 再由下面推出 然后再加上一个t=3的节点 然后再算v的子节点
取最大值就行 没写明白wa了好久
#include<bits/stdc++.h>
#define close std::ios::sync_with_stdio(false),cin.tie(0),cout.tie(0)
using namespace std;
typedef long long ll;
const ll MAXN = 4e5+7;
const ll mod = 1e9+7;
const ll inf = 0x3f3f3f3f;
#define int ll
int a[MAXN],b[MAXN];
vector<int> adj[MAXN];
int dp[MAXN],sum[MAXN];
void dfs(int u,int fa) {
dp[u]=a[u];
int tmp=0;
int max_1=0;
int max_2=0;
for(auto v:adj[u]) {
if(v==fa) continue;
sum[u]+=a[v];
dfs(v,u);
tmp=max(tmp,a[v]);
if(b[v]==3) {
if(a[v]>a[max_1]) {
max_2=max_1;
max_1=v;
} else if(a[v]>a[max_2]) {
max_2=v;
}
}
dp[u]+=dp[v];
dp[u]-=a[v];
}
int temp=dp[u];
for(auto &v:adj[u]){
if(v==fa) continue;
int k=a[v];
for(auto &it:adj[v]){
if(it==u) continue;
k+=dp[it]-a[it];
}
if(v==max_1)
dp[u]=max({temp+tmp,temp-dp[v]+a[v]+k+a[max_2],dp[u]});
else dp[u]=max({temp+tmp,temp-dp[v]+a[v]+k+a[max_1],dp[u]});
}
dp[u]=max(dp[u],temp+tmp);
}
void solve() {
int n;
cin>>n;
for(int i=1; i<=n; i++) cin>>a[i];
for(int i=1; i<=n; i++) {
cin>>b[i];
if(b[i]==2) b[i]=1;
adj[i].clear();
dp[i]=0;
sum[i]=0;
}
for(int i=1; i<n; i++) {
int u,v;
cin>>u>>v;
adj[u].push_back(v);
adj[v].push_back(u);
}
sum[0]=inf;
dfs(1,0);
cout<<dp[1]<<'\n';
}
signed main() {
close;
int t;
cin>>t;
while(t--)
solve();
}
M. Windblume Festival
手玩一下发现结论 至少有一个改变符号 然后最多有n-1个改变符号 特判n=1的情况即可
改变符号贪心
#include <iostream>
#include <vector>
#include <stack>
#include <map>
#include <set>
#include <queue>
#include <string>
#include <algorithm>
#include <iomanip> //fixed<<setprecision(12)<<
#include <utility> //pair模板
#include <cmath>
#include <random> //mt19937 mtrand(time(0));
#include <time.h>
#define close \
std::ios::sync_with_stdio(false); \
cin.tie(0); \
cout.tie(0)
typedef long long ll;
typedef unsigned long long ull;
const int N = 2e6 + 7;
const ll mod = 200907;
using namespace std;
ll n, a[N], ans, sum;
void solve()
{
// freopen("data.in.txt","r",stdin);
// freopen("data.out.txt","w",stdout);
cin >> n;
ans = sum = 0;
for (int i = 1; i <= n; i++)
{
cin >> a[i];
}
if (n == 1)
{
cout << a[1] << endl;
return;
}
sort(a + 1, a + 1 + n);
for (int i = 1; i <= n; i++)
{
if (i == 1)
sum -= a[i];
else if (i == n)
sum += a[i];
else
{
if (a[i] < 0)
sum -= a[i];
else
sum += a[i];
}
}
cout << sum << endl;
}
int main()
{
close;
int t = 1;
cin >> t;
while (t--)
{
solve();
}
return 0;
}
E. Paimon Segment Tree
历史和是一种线性的递推 可以由上一个递推过来 由此想到矩阵处理 因此用线段树维护矩阵 加val之后相当于乘矩阵 把求历史和过程中要用的全用矩阵维护好先
有点卡常 少取模!!尽量优化下矩阵 乘法只做一半之类的
#include<bits/stdc++.h>
#define close std::ios::sync_with_stdio(false),cin.tie(0),cout.tie(0)
using namespace std;
typedef long long ll;
const ll MAXN = 5e4+7;
const ll mod = 1e9+7;
const ll inf = 0x3f3f3f3f;
const ll M = 4;
inline ll read() { //快读
ll x=0,f=0;
char ch=getchar();
while(ch>'9'||ch<'0') {
f|=(ch=='-');
ch=getchar();
}
while(ch<='9'&&ch>='0') {
x=(x<<1LL)+(x<<3LL)+
(ch^48);
ch=getchar();
}
return f?-x:x;
}
struct matrix {
ll x[M+1][M+1];
matrix() {
memset(x,0,sizeof(x));
}
ll* operator [] (int i) {
return x[i];
}
matrix operator * (matrix b) const {
matrix res;
for(int i = 1; i <= M; i ++) {
for(int j = 1; j <= M; j ++) {
for(int k = i; k <= j; k ++) {
res[i][j] += (( x[i][k] *b[k][j]) );
res[i][j]%=mod;
}
}
}
return res;
}
matrix operator + ( matrix b) const {
matrix res;
for (int i = 1; i <=M; i ++) {
for (int j = i; j <= M; j ++) {
res[i][j] = (x[i][j] + b[i][j] );
res[i][j]%=mod;
}
}
return res;
}
bool operator != (matrix b) {
for (int i = 1; i <= M; i ++) {
for (int j = 1; j <=M; j ++) {
if (x[i][j] != b[i][j])return true;
}
}
return false;
}
void init() {
for(int i = 1 ; i <=M ; i ++) {
for(int j = i ; j <=M ; j ++) {
x[i][j] = (i == j ? 1LL : 0LL);
}
}
}
};
matrix mpow(matrix a,ll m) { //矩阵a的m次方
matrix res;
res.init();
while(m>0) {
if(m&1) res=res*a;
a=a*a;
m>>=1;
}
return res;
}
bool check(matrix a) {
int flag=true;
for(int i=1; i<=M; i++) {
for(int j=1; j<=M; j++) {
if(i!=j&&a.x[i][j]!=0) flag=false;
else if(i==j&&a.x[i][j]!=1) flag=false;
}
}
return flag;
}
struct Info {
matrix sum;
};
Info operator +(const Info &a,const Info &b) {
Info c;
c.sum=a.sum+b.sum;
return c;
}
matrix A;
ll a[MAXN];
struct node {
matrix lazy;
Info val;
} seg[MAXN<<2];
void up(int id) {
seg[id].val=seg[id<<1].val+seg[id<<1|1].val;
}
void settag(int id,int l,int r,matrix tag) {
matrix tmp;
seg[id].val.sum=seg[id].val.sum*tag;
seg[id].lazy=seg[id].lazy*tag;
}
void down(int id,int l,int r) {
if(seg[id].lazy.x[3][4]==0) return;
int mid=l+r>>1;
settag(id<<1,l,mid,seg[id].lazy);
settag(id<<1|1,mid+1,r,seg[id].lazy);
seg[id].lazy.init();
}
void build(int id,int l,int r) {
seg[id].lazy.init();
if(l==r) {
seg[id].val.sum[1][1]=1;
seg[id].val.sum[1][2]=a[l];
seg[id].val.sum[1][3]=a[l]*a[l]%mod;
seg[id].val.sum[1][4]=a[l]*a[l]%mod;
return;
}
int mid = l+r>>1;
build(id<<1,l,mid);
build(id<<1|1,mid+1,r);
up(id);
}
void modify(int id,int l,int r,int ql,int qr,matrix val) {
if (ql==l&&r==qr) {
settag(id,l,r,val);
return;
}
down(id,l,r);
int mid =(l+r) >> 1;
if (qr<=mid)
modify(id <<1,l,mid,ql,qr,val);
else if (ql>mid)
modify(id<<1|1, mid+1,r,ql,qr,val);
else {
modify(id<<1,l,mid,ql,mid,val);
modify(id<<1|1,mid+1,r,mid+1,qr,val);
}
up(id);
}
Info query(int id,int l ,int r,int ql,int qr) {
if(ql==l&&r==qr) {
return seg[id].val;
}
down(id,l,r);
int mid=l+r>>1;
if(qr<=mid) return query(id<<1,l,mid,ql,qr);
else if(ql>mid) return query(id<<1|1,mid+1,r,ql,qr);
else return query(id<<1,l,mid,ql,mid)+query(id<<1|1,mid+1,r,mid+1,qr);
}
vector<array<int,3> > P;
vector<array<int,4> > Q[MAXN];//id l r ty
ll ans[MAXN];
void solve() {
int n,m,q;
// cin>>n>>m>>q;
n=read();
m=read();
q=read();
for(int i=1; i<=n; i++) a[i]=read();
build(1,1,n);
P.push_back({0,0,0});
for(int i=1; i<=m; i++) {
int l,r,x;
// cin>>l>>r>>x;
l=read();
r=read();
x=read();
P.push_back({l,r,x});
}
for(int i=1; i<=q; i++) {
int l,r,x,y;
// cin>>l>>r>>x>>y;
l=read();
r=read();
x=read();
y=read();
if(x!=0)
Q[x-1].push_back({i,l,r,-1});
Q[y].push_back({i,l,r,1});
}
for(auto it:Q[0]) {
int id=it[0],l=it[1],r=it[2],ty=it[3];
matrix tmp = query(1,1,n,l,r).sum;
ans[id]+=ty*tmp[1][4];
}
for(int i=1; i<=m; i++) {
int l=P[i][0],r=P[i][1],x=P[i][2];
matrix tmp;
tmp[1][1]=1;
tmp[1][2]=x;
tmp[1][3]=1LL*x*x%mod;
tmp[1][4]=1LL*x*x%mod;
tmp[2][2]=1;
tmp[2][3]=2LL*x;
tmp[2][4]=2LL*x;
tmp[3][3]=1;
tmp[3][4]=1;
tmp[4][4]=1;
modify(1,1,n,l,r,tmp);
tmp.init();
tmp[3][4]=1;
if(l>1) {
modify(1,1,n,1,l-1,tmp);
}
if(r<n) {
modify(1,1,n,r+1,n,tmp);
}
for(auto it:Q[i]) {
int id=it[0],l=it[1],r=it[2],ty=it[3];
matrix tmp = query(1,1,n,l,r).sum;
ans[id]+=ty*tmp[1][4];
}
}
for(int i=1; i<=q; i++) {
printf("%lld\n",(ans[i]%mod+mod)%mod);
// cout<<(ans[i]%mod+mod)%mod<<"\n";
}
}
signed main() {
// close;
solve();
}
J. Xingqiu’s Joke
找因子用的很暴力 不会证明复杂度的办法
4.2020-2021 ACM-ICPC, Asia Nanjing Regional Contest (XXI Open Cup, Grand Prix of Nanjing)
赛时过题EKL 补题AFHM
E. Evil Coordinate
重新排列路径 然后让路径不会经过某个点
顺时针方向绕着走好像就行了 赛时不小心 写挂了好久
#include<bits/stdc++.h>
#define close std::ios::sync_with_stdio(false),cin.tie(0),cout.tie(0)
using namespace std;
typedef long long ll;
const ll MAXN = 3e5+7;
const ll mod = 1e9+7;
const ll inf = 0x3f3f3f3f;
#define int ll
int fx[4][2]= {1,0,0,1,-1,0,0,-1}; //右 上 左 下
int f[4];
string str[4]= {"R","U","L","D"};
void solve() {
int x,y;
cin>>x>>y;
string s;
cin>>s;
string ans;
for(int i=0; i<4; i++) f[i]=0;
for(auto ch :s) {
if(ch=='R') f[0]++;
else if(ch=='U') f[1]++;
else if(ch=='L') f[2]++;
else f[3]++;
}
int xx=f[0]-f[2];
int yy=f[1]-f[3];
if((xx==x&&yy==y)||(x==0&&y==0)) {
cout<<"Impossible\n";
return;
}
int px=0,py=0;
int flag1=1,flag2=1,flag3=1,flag4=1;
for(int i=0;i<4;i++){
for(int j=1;j<=f[i];j++){
px+=fx[i][0];
py+=fx[i][1];
if(px==x&&py==y) flag1=0;
}
}
px=0;
py=0;
for(int i=0;i<4;i++){
int p=(i+1)%4;
for(int j=1;j<=f[p];j++){
px+=fx[p][0];
py+=fx[p][1];
if(px==x&&py==y) flag2=0;
}
}
px=0;
py=0;
for(int i=0;i<4;i++){
int p=(i+2)%4;
for(int j=1;j<=f[p];j++){
px+=fx[p][0];
py+=fx[p][1];
if(px==x&&py==y) flag3=0;
}
}
px=0;
py=0;
for(int i=0;i<4;i++){
int p=(i+3)%4;
for(int j=1;j<=f[p];j++){
px+=fx[p][0];
py+=fx[p][1];
if(px==x&&py==y) flag4=0;
}
}
// cout<<flag1<<" "<<flag2<<" "<<flag3<<" "<<flag4<<'\n';
if(flag1){
for(int i=0;i<4;i++){
for(int j=1;j<=f[i];j++){
cout<<str[i];
}
}
}
else if(flag2){
for(int i=0;i<4;i++){
int p=(i+1)%4;
for(int j=1;j<=f[p];j++){
cout<<str[p];
}
}
}
else if(flag3){
for(int i=0;i<4;i++){
int p=(i+2)%4;
for(int j=1;j<=f[p];j++){
cout<<str[p];
}
}
}
else if(flag4){
for(int i=0;i<4;i++){
int p=(i+3)%4;
for(int j=1;j<=f[p];j++){
cout<<str[p];
}
}
}
else{
cout<<"Impossible";
}
cout<<'\n';
}
signed main() {
int t;
cin>>t;
while(t--)
solve();
}
K. K Co-prime Permutation
显然 当i位置上是i+1时 gcd必为1 否则为i时 gcd为i 推一下就行
#include<bits/stdc++.h>
#define close std::ios::sync_with_stdio(false),cin.tie(0),cout.tie(0)
using namespace std;
typedef long long ll;
const ll MAXN = 3e5+7;
const ll mod = 1e9+7;
const ll inf = 0x3f3f3f3f;
void solve(){
int n,k;cin>>n>>k;
if(k==0){
cout<<"-1";
}
else{
k--;
for(int i=1;i<=k;i++){
cout<<i+1<<" ";
}
cout<<"1 ";
for(int i=k+2;i<=n;i++){
cout<<i<<" ";
}
}
}
signed main(){
close;
solve();
}
L. Let’s Play Curling
没记错就是找两个蓝色石头中间最大红色数量
#include <iostream>
#include <vector>
#include <stack>
#include <map>
#include <set>
#include <queue>
#include <string>
#include <algorithm>
#include <iomanip> //fixed<<setprecision(12)<<
#include <utility> //pair模板
#include <cmath>
#include <random> //mt19937 mtrand(time(0));
#include <time.h>
#define close \
std::ios::sync_with_stdio(false); \
cin.tie(0); \
cout.tie(0)
typedef long long ll;
typedef unsigned long long ull;
const int inf = 2e9;
const int N = 2e6 + 7;
const ll mod = 200907;
using namespace std;
int n, m;
vector<int> all, a, b;
void solve()
{
// freopen("data.in.txt","r",stdin);
// freopen("data.out.txt","w",stdout);
cin >> n >> m;
all.clear(), a.clear(), b.clear();
for (int i = 1; i <= n; i++)
{
int tp;
cin >> tp;
// cout << tp << ' ';
a.push_back(tp);
all.push_back(tp);
}
// cout << endl;
for (int i = 1; i <= m; i++)
{
int tp;
cin >> tp;
b.push_back(tp);
all.push_back(tp);
}
sort(a.begin(), a.end());
sort(b.begin(), b.end());
sort(all.begin(), all.end());
all.erase(unique(all.begin(), all.end()), all.end());
// for (int i = 0; i < all.size(); i++)
// cout << all[i] << ' ';
// cout << endl;
for (int i = 0; i < a.size(); i++)
{
int tp = a[i];
a[i] = lower_bound(all.begin(), all.end(), tp) - all.begin() + 1;
// cout << a[i] << endl;
}
// cout << endl;
for (int i = 0; i < b.size(); i++)
b[i] = lower_bound(all.begin(), all.end(), b[i]) - all.begin() + 1;
// cout << endl;
int mx = 0;
for (int i = 0; i < b.size() - 1; i++)
{
int l = upper_bound(a.begin(), a.end(), b[i]) - a.begin() + 1;
int r = lower_bound(a.begin(), a.end(), b[i + 1]) - a.begin() + 1;
// cout << l << ' ' << r << endl;
mx = max(mx, r - l);
}
int l = upper_bound(a.begin(), a.end(), b[m - 1]) - a.begin() + 1;
int r = lower_bound(a.begin(), a.end(), inf) - a.begin() + 1;
mx = max(mx, r - l);
l = 1;
r = lower_bound(a.begin(), a.end(), b[0]) - a.begin() + 1;
mx = max(mx, r - l);
if (mx == 0)
cout << "Impossible" << endl;
else
cout << mx << endl;
}
int main()
{
close;
int t = 1;
cin >> t;
while (t--)
{
solve();
}
return 0;
}
A. Ah, It’s Yesterday Once More
额场上写差不多了 但是有一个孤立点没找到 寄了 就是斜着走
F. Fireworks
先推出期望计算公式 然后三分答案 场上三分太丑 挂了
#include<bits/stdc++.h>
#define close std::ios::sync_with_stdio(false),cin.tie(0),cout.tie(0)
using namespace std;
typedef long long ll;
const ll MAXN = 3e5+7;
const ll mod = 1e9+7;
const ll inf = 0x3f3f3f3f;
#define double long double
double f(int x,int n,int m,double p){
return ((double)x*n+m)/(1.0-(pow(1-p,x)));
}
void solve(){
int n,m;
double p;
cin>>n>>m>>p;
p/=10000.0;
int l=0,r=inf;
while(l<r){
int mid1=l+(r-l)/3;
int mid2=r-(r-l)/3;
if(f(mid1,n,m,p)<f(mid2,n,m,p)) r=mid2-1;
else l=mid1+1;
}
printf("%.8Lf\n",f(l,n,m,p));
}
signed main(){
int t;cin>>t;
while(t--)
solve();
}
H. Harmonious Rectangle
小范围打表
M. Monster Hunter
感觉类似树上背包 枚举父亲贡献的节点与我与我邻居贡献的
#include<bits/stdc++.h>
#define close std::ios::sync_with_stdio(false),cin.tie(0),cout.tie(0)
using namespace std;
typedef long long ll;
const ll MAXN = 3e3+7;
const ll mod = 1e9+7;
const ll inf = 0x3f3f3f3f;
#define int ll
int dp[MAXN][MAXN][2],a[MAXN];// i为顶点的子树 已经用了j个 此时用/不用 减少的最大贡献
vector<int> adj[MAXN];
int n;
int ans=0;
int sum[MAXN];
int sz[MAXN];
void dfs_sum(int u,int fa) {
sum[u]=a[u];
sz[u]=1;
for(auto &v:adj[u]) {
sum[u]+=a[v];
dfs_sum(v,u);
}
ans+=sum[u];
}
void dfs(int u,int fa) {
dp[u][1][1]=sum[u];
for(auto &v:adj[u]) {
dfs(v,u);
for(int i=sz[u]; i>=0; i--) { //枚举父节点删了几个
for(int j=sz[v];j>=0;j--){
if(j>0)
dp[u][j+i][0]=max(dp[u][j+i][0],dp[u][i][0]+max(dp[v][j][0],dp[v][j][1]+a[v]));
else
dp[u][j+i][0]=max(dp[u][j+i][0],dp[u][i][0]+dp[v][j][0]);
if(j>0&&i>0)
dp[u][j+i][1]=max(dp[u][j+i][1],dp[u][i][1]+max(dp[v][j][0],dp[v][j][1]));
else if(i>0)
dp[u][j+i][1]=max(dp[u][j+i][1],dp[u][i][1]+dp[v][j][0]);
}
}
sz[u]+=sz[v];
}
// cout<<"delet : u "<<u<<"\n";
// for(int i=0;i<=n;i++) cout<<"i = "<<i<<" "<<dp[u][i][0]<<" "<<dp[u][i][1]<<"\n";
}
void solve() {
cin>>n;
for(int i=1; i<=n; i++) {
adj[i].clear();
sum[i]=0;
for(int j=0; j<=n; j++) dp[i][j][0]=dp[i][j][1]=0;
}
ans=0;
for(int i=2; i<=n; i++) {
int u;
cin>>u;
adj[u].push_back(i);
}
for(int i=1; i<=n; i++) cin>>a[i];
dfs_sum(1,0);
dfs(1,0);
for(int i=0; i<=n; i++) {
cout<<ans-max(dp[1][i][0],dp[1][i][1])<<" ";
}
cout<<"\n";
}
signed main() {
int t;
cin>>t;
while(t--)
solve();
}
5.2022 ICPC Southeastern Europe Regional Contest
赛时过题 AFGHN
A. AppendAppendAppend
一个一个遍历 然后指针二分找下一个的位置 超了+1
#include <iostream>
#include <vector>
#include <stack>
#include <map>
#include <set>
#include <queue>
#include <string>
#include <algorithm>
#include <iomanip> //fixed<<setprecision(12)<<
#include <utility> //pair模板
#include <cmath>
#include <random> //mt19937 mtrand(time(0));
#include <time.h>
#define close \
std::ios::sync_with_stdio(false); \
cin.tie(0); \
cout.tie(0)
typedef long long ll;
typedef unsigned long long ull;
const int N = 2e5 + 7;
const ll mod = 200907;
using namespace std;
string s, t;
vector<int> pos[40];
void solve()
{
// freopen("data.in.txt","r",stdin);
// freopen("data.out.txt","w",stdout);
cin >> s >> t;
for (int i = 0; i < s.length(); i++)
pos[s[i] - 'a'].push_back(i);
int ans = 0, now = 0;
for (int i = 0; i < t.length(); i++)
{
int j = t[i] - 'a';
int nx = lower_bound(pos[j].begin(), pos[j].end(), now) - pos[j].begin();
// cout << i << ' ' << now << ' ' << t[i] << ' ' << nx << endl;
if (nx < pos[j].size())
now = pos[j][nx] + 1;
else
now = 0, i--, ans++;
}
cout << ans + 1;
}
int main()
{
close;
int t = 1;
// cin>>t;
while (t--)
{
solve();
}
return 0;
}
F. Fortune over Sportsmanship
模拟一下怎么交换 正解应该是dp 不过可能差不多
#include <iostream>
#include <vector>
#include <stack>
#include <map>
#include <set>
#include <queue>
#include <string>
#include <algorithm>
#include <iomanip> //fixed<<setprecision(12)<<
#include <utility> //pair模板
#include <cmath>
#include <random> //mt19937 mtrand(time(0));
#include <time.h>
#define close \
std::ios::sync_with_stdio(false); \
cin.tie(0); \
cout.tie(0)
typedef long long ll;
typedef unsigned long long ull;
const int N = 2e3 + 7;
const ll mod = 200907;
using namespace std;
int n;
ll a[N][N];
vector<pair<int, int>> v;
void solve()
{
// freopen("data.in.txt","r",stdin);
// freopen("data.out.txt","w",stdout);
cin >> n;
for (int i = 1; i <= n; i++)
for (int j = 1; j <= n; j++)
cin >> a[i][j];
ll ans = 0;
for (int i = n; i > 1; i--)
{
ll mx = 0, idx = 0;
for (int j = 1; j < i; j++)
if (mx <= a[j][i])
mx = a[j][i], idx = j;
ans += mx;
// cout << idx << ' ' << i << endl;
v.push_back({idx, i});
for (int j = 1; j < idx; j++)
{
a[j][idx] = max(a[j][idx], a[j][i]);
}
for (int j = idx + 1; j <= n; j++)
{
a[idx][j] = max(a[idx][j], a[j][i]);
}
// for (int j = 1; j <= n; j++)
// {
// for (int k = 1; k <= n; k++)
// cout << a[j][k] << ' ';
// cout << endl;
// }
// cout << endl;
}
cout << ans << endl;
for (auto i : v)
{
cout << i.first << ' ' << i.second << endl;
}
}
int main()
{
close;
int t = 1;
// cin>>t;
while (t--)
{
solve();
}
return 0;
}
G. Gears
设第一个齿轮大小为x 后面的均能用x表示 然后二分一下x的大小 看看区间内是否有不满足的 根据实际情况return true或者false
#include <iostream>
#include <vector>
#include <stack>
#include <map>
#include <set>
#include <queue>
#include <string>
#include <algorithm>
#include <iomanip> //fixed<<setprecision(12)<<
#include <utility> //pair模板
#include <cmath>
#include <random> //mt19937 mtrand(time(0));
#include <time.h>
#define close \
std::ios::sync_with_stdio(false); \
cin.tie(0); \
cout.tie(0)
typedef long long ll;
typedef unsigned long long ull;
#define int ll
const int N = 5e5 + 7;
const ll mod = 200907;
using namespace std;
int n;
int a[N];
int b[N];
int c[N];
int R[N];
int sum=0;
int mins=1e9+7;
int maxs=0;
bool check(int mid) {
int tmp=0;
for(int i=1; i<=n; i++) {
if(i%2==1) {
tmp+=mid+c[i];
if(mid+c[i]<mins){
return true;
}
else if(mid+c[i]>maxs){
return false;
}
} else {
tmp+=c[i]-mid;
if(c[i]-mid<mins){
return false;
}
else if(c[i]-mid>maxs){
return true;
}
}
// cout<<"# "<<tmp<<'\n';
}
if(tmp>=sum) return false;
else return true;
}
void solve() {
cin>>n;
for(int i=1; i<=n; i++) cin>>a[i];
for(int i=1; i<=n; i++) {
cin>>R[i];
sum+=R[i];
maxs=max(maxs,R[i]);
mins=min(mins,R[i]);
}
for(int i=2; i<=n; i++) {
b[i]=a[i]-a[i-1];
}
for(int i=1; i<=n; i++) {
if(i==1) c[i]=0;
else {
c[i]=b[i]-c[i-1];
}
}
int l=1,r=1e9+7;
while(l<=r) {
int mid=l+r>>1;
if(check(mid)) {
l=mid+1;
} else {
r=mid-1;
}
}
// cout<<l<<" "<<r<<"\n";
for(int i=1; i<=n; i++) {
if(i%2==1) {
cout<<l+c[i];
} else cout<<c[i]-l;
cout<<" ";
}
// freopen("data.in.txt","r",stdin);
// freopen("data.out.txt","w",stdout);
}
signed main() {
close;
int t = 1;
// cin>>t;
while (t--) {
solve();
}
return 0;
}
H. Hanoi
汉诺塔 1可以不受限制
#include <iostream>
#include <vector>
#include <stack>
#include <map>
#include <set>
#include <queue>
#include <string>
#include <algorithm>
#include <iomanip> //fixed<<setprecision(12)<<
#include <utility> //pair模板
#include <cmath>
#include <random> //mt19937 mtrand(time(0));
#include <time.h>
#define close \
std::ios::sync_with_stdio(false); \
cin.tie(0); \
cout.tie(0)
typedef long long ll;
typedef unsigned long long ull;
const int N = 2e5 + 7;
const ll mod = 200907;
using namespace std;
int n;
stack<int> st1, st2, st3;
vector<string> ans;
void add(int k)
{
stack<int> temp;
while (st3.size() && k > st3.top())
{
temp.push(st3.top());
st3.pop();
ans.push_back("3 1");
}
st3.push(k);
ans.push_back("2 3");
while (temp.size())
{
st3.push(temp.top());
temp.pop();
ans.push_back("1 3");
}
}
void solve()
{
// freopen("data.in.txt","r",stdin);
// freopen("data.out.txt","w",stdout);
cin >> n;
for (int i = 1, tp; i <= n; i++)
{
cin >> tp;
st1.push(tp);
}
for (int i = n; i > 0; i--)
{
int tp = st1.top();
st1.pop();
ans.push_back("1 2");
add(tp);
}
cout << ans.size() << endl;
for (auto i : ans)
cout << i << endl;
}
int main()
{
close;
int t = 1;
// cin>>t;
while (t--)
{
solve();
}
return 0;
}
N. Nusret Gökçe
让每个相邻的值的差不超过k 使用搜索 分别往左往右递减 遇到大的就从那个地方开始搜 遇到小的并且搜过就return 应该是O(n)
#include <iostream>
#include <vector>
#include <stack>
#include <map>
#include <set>
#include <queue>
#include <string>
#include <algorithm>
#include <iomanip> //fixed<<setprecision(12)<<
#include <utility> //pair模板
#include <cmath>
#include <random> //mt19937 mtrand(time(0));
#include <time.h>
#define close \
std::ios::sync_with_stdio(false); \
cin.tie(0); \
cout.tie(0)
typedef long long ll;
typedef unsigned long long ull;
const int N = 2e5 + 7;
const ll mod = 200907;
using namespace std;
#define int ll
int a[N],f[N];
int n,m;
void dfs(int x){
int l=x,r=x;
f[x]=max(f[x],a[x]);
int now=a[x]-m;
for(int i=r+1;i<=n;i++){
if(f[i]<=now&&a[i]<=now){
f[i]=now;
now-=m;
}
else if(f[i]==0){
dfs(i);
break;
}
else if(f[i]>now) break;
}
now=a[x]-m;
for(int i=l-1;i>=1;i--){
if(f[i]<=now&&a[i]<=now){
f[i]=now;
now-=m;
}
else if(f[i]==0){
dfs(i);
break;
}
else if(f[i]>now) break;
}
}
void solve()
{
cin>>n>>m;
int maxp=0;
for(int i=1;i<=n;i++){
cin>>a[i];
if(a[i]>a[maxp]) maxp=i;
}
f[maxp]=a[maxp];
dfs(maxp);
for(int i=1;i<=n;i++){
cout<<f[i]<<" ";
}
}
signed main()
{
close;
int t = 1;
// cin>>t;
while (t--)
{
solve();
}
return 0;
}
6.The 15th Chinese Northeast Collegiate Programming Contest
赛时过题CEIKM 补题ACDHJ
C. Vertex Deletion
树dp 队友推了很牛的式子 然后dp
#include <iostream>
#include <vector>
#include <stack>
#include <map>
#include <set>
#include <queue>
#include <string>
#include <algorithm>
#include <iomanip> //fixed<<setprecision(12)<<
#include <utility> //pair模板
#include <cmath>
#include <random> //mt19937 mtrand(time(0));
#include <time.h>
#define close \
std::ios::sync_with_stdio(false); \
cin.tie(0); \
cout.tie(0)
typedef long long ll;
#define int ll
typedef unsigned long long ull;
const double pi = 3.141592653589793;
const int N = 2e5 + 7;
const int MAXN = 2e5 + 7;
const ll mod = 998244353;
using namespace std;
vector<int> adj[MAXN];
int dp[MAXN][3],sz[MAXN];
void dfs(int u,int fa){
dp[u][0]=1;
dp[u][1]=1;
dp[u][2]=1;
for(auto &v:adj[u]){
if(v==fa) continue;
dfs(v,u);
dp[u][2]*=dp[v][0];
dp[u][2]%=mod;
}
for(auto &v:adj[u]){
if(v==fa) continue;
dp[u][0]*=(dp[v][0]+dp[v][1]);
dp[u][0]%=mod;
}
for(auto &v:adj[u]){
if(v==fa) continue;
dp[u][1]*=(dp[v][0]+dp[v][1]+dp[v][2]);
dp[u][1]%=mod;
}
dp[u][1]-=dp[u][2];
dp[u][1]%=mod;
dp[u][1]=(dp[u][1]+mod)%mod;
// cout<<"# u : "<<u<<"\n";
// cout<<dp[u][0]<<" "<<dp[u][1]<<' '<<dp[u][2]<<'\n';
}
void solve()
{
// freopen("data.in.txt","r",stdin);
// freopen("data.out.txt","w",stdout);
int n;
cin>>n;
for(int i=1;i<=n;i++) adj[i].clear();
for(int i=1;i<n;i++){
int u,v;cin>>u>>v;
adj[u].push_back(v);
adj[v].push_back(u);
}
dfs(1,0);
cout<<(dp[1][0]+dp[1][1])%mod<<"\n";
}
signed main()
{
close;
int t = 1;
cin>>t;
while (t--)
{
solve();
}
return 0;
}
E. Easy Math Problem
观察了一下发现要变成6的倍数
#include <iostream>
#include <vector>
#include <stack>
#include <map>
#include <set>
#include <queue>
#include <string>
#include <algorithm>
#include <iomanip> //fixed<<setprecision(12)<<
#include <utility> //pair模板
#include <cmath>
#include <random> //mt19937 mtrand(time(0));
#include <time.h>
#define close \
std::ios::sync_with_stdio(false); \
cin.tie(0); \
cout.tie(0)
typedef long long ll;
typedef unsigned long long ull;
const double pi = 3.141592653589793;
const int N = 2e5 + 7;
const ll mod = 200907;
using namespace std;
void solve()
{
ll n;
cin >> n;
cout << n * 6ll << ' ' << 3 << '\n';
cout << 1ll * n << " " << 2ll * n << " " << 3ll * n << '\n';
// freopen("data.in.txt","r",stdin);
// freopen("data.out.txt","w",stdout);
}
int main()
{
close;
int t = 1;
cin >> t;
while (t--)
{
solve();
}
return 0;
}
I. Takeaway
特判 签到
#include <iostream>
#include <vector>
#include <stack>
#include <map>
#include <set>
#include <queue>
#include <string>
#include <algorithm>
#include <iomanip> //fixed<<setprecision(12)<<
#include <utility> //pair模板
#include <cmath>
#include <random> //mt19937 mtrand(time(0));
#include <time.h>
#define close \
std::ios::sync_with_stdio(false); \
cin.tie(0); \
cout.tie(0)
typedef long long ll;
#define int ll
typedef unsigned long long ull;
const double pi = 3.141592653589793;
const int N = 2e5 + 7;
const ll mod = 200907;
using namespace std;
int f[8] = {0, 7, 27, 41, 49, 63, 78, 108};
void solve()
{
// freopen("data.in.txt","r",stdin);
// freopen("data.out.txt","w",stdout);
int n;
cin >> n;
int sum = 0;
for (int i = 1; i <= n; i++)
{
int a;
cin >> a;
sum += f[a];
}
if (sum >= 120)
{
cout << sum - 50 << "\n";
}
else if (sum >= 89)
{
cout << sum - 30 << '\n';
}
else if (sum >= 69)
{
cout << sum - 15 << "\n";
}
else
cout << sum << "\n";
}
signed main()
{
close;
int t = 1;
cin >> t;
while (t--)
{
solve();
}
return 0;
}
K. City
#include <iostream>
#include <vector>
#include <stack>
#include <map>
#include <set>
#include <queue>
#include <string>
#include <algorithm>
#include <iomanip> //fixed<<setprecision(12)<<
#include <utility> //pair模板
#include <cmath>
#include <random> //mt19937 mtrand(time(0));
#include <time.h>
#define close \
std::ios::sync_with_stdio(false); \
cin.tie(0); \
cout.tie(0)
typedef long long ll;
typedef unsigned long long ull;
const double pi = 3.141592653589793;
const int N = 2e5 + 7;
const ll mod = 200907;
using namespace std;
#define int long long
struct node
{
int x, y;
int w;
friend bool operator<(const node &a, const node &b)
{
return a.w > b.w;
}
} edg[N];
struct quest
{
int id;
int w;
int res;
friend bool operator<(const quest &a, const quest &b)
{
return a.w > b.w;
}
} que[N];
bool cmp(quest a, quest b)
{
return a.id < b.id;
}
int p[N], siz[N];
int find(int x)
{
if (p[x] != x)
p[x] = find(p[x]);
return p[x];
}
void solve()
{
int n, m, q;
cin >> n >> m >> q;
for (int i = 1; i <= m; i++)
{
cin >> edg[i].x >> edg[i].y >> edg[i].w;
}
for (int i = 1; i <= q; i++)
{
cin >> que[i].w;
que[i].id = i;
}
sort(edg + 1, edg + 1 + m);
sort(que + 1, que + 1 + q);
for (int i = 1; i <= n; i++)
{
p[i] = i;
siz[i] = 1;
}
// for (int i = 1; i <= n; i++)
// {
// cout << edg[i].w << ' ';
// }
// cout << '\n';
// for (int i = 1; i <= q; i++)
// {
// cout << que[i].w << ' ';
// }
// cout << '\n';
int now = 1, ans = 0;
for (int i = 1; i <= m; i++)
{
if (edg[i].w >= que[now].w)
{
int a = edg[i].x;
int b = edg[i].y;
if (find(a) == find(b))
{
continue;
}
// ans -= siz[find(b)] * (siz[find(b)] - 1) / 2;
// ans -= siz[find(a)] * (siz[find(a)] - 1) / 2;
ans += siz[find(b)] * siz[find(a)];
siz[find(b)] += siz[find(a)];
p[find(a)] = find(b);
// ans += siz[find(b)] * (siz[find(b)] - 1) / 2;
}
else
{
que[now].res = ans;
i--;
now++;
if (now > q)
break;
}
// cout << ans << ' ';
}
// cout << now << '\n';
for (int i = now; i <= q; i++)
{
// cout << i << "cnm";
que[i].res = ans;
}
// cout << '\n';
sort(que + 1, que + 1 + q, cmp);
for (int i = 1; i <= q; i++)
{
cout << que[i].res << '\n';
}
// freopen("data.in.txt","r",stdin);
// freopen("data.out.txt","w",stdout);
}
signed main()
{
close;
int t = 1;
cin >> t;
while (t--)
{
solve();
}
return 0;
}
M. Master of Shuangpin
写脑残了
#include<stdio.h>
#include<string.h>
char s[2000];
int main() {
while(gets(s)!=NULL) {
int n=strlen(s);
int flag=1;
for(int i=0; i<n; i++) {
if(flag==1) {
flag=0;
if(s[i+1]==' '||i==n-1){
printf("%c%c",s[i],s[i]);
continue;
}
else if(s[i+2]==' '||i+1==n-1){
printf("%c%c",s[i],s[i+1]);
i++;
continue;
}
if(s[i+1]=='h'){
if(s[i]=='c') {
if(s[i+2]==' '||i+1==n-1) printf("c");
printf("i");
i++;
continue;
} else if(s[i]=='s') {
if(s[i+2]==' '||i+1==n-1) printf("s");
printf("u");
i++;
continue;
} else if(s[i]=='z') {
if(s[i+2]==' '||i+1==n-1) printf("z");
printf("v");
i++; continue;
}
} else if(s[i+1]=='i') {
if(s[i]=='a') {
if(s[i+2]==' '||i+1==n-1) printf("a");
printf("d");
i++; continue;
} else if(s[i]=='e') {
if(s[i+2]==' '||i+1==n-1) printf("e");
printf("w");
i++; continue;
}
} else if(s[i+1]=='n') {
if(s[i]=='a'&&s[i+2]!='g') {
if(s[i+2]==' '||i+1==n-1) printf("a");
printf("j");
i++; continue;
} else if(s[i]=='a'&&s[i+2]=='g') {
if(s[i+3]==' '||i+2==n-1) printf("a");
printf("h");
i+=2; continue;
} else if(s[i]=='e'&&s[i+2]!='g') {
if(s[i+2]==' '||i+1==n-1) printf("e");
printf("f");
i++; continue;
}
else if(s[i]=='e'&&s[i+2]=='g'){
if(s[i+3]==' '||i+2==n-1) printf("e");
printf("g");
i+=2; continue;
}
} else if(s[i+1]=='u') {
if(s[i]=='o') {
if(s[i+2]==' '||i+1==n-1) printf("o");
printf("z");
i++; continue;
}
}
else if(s[i+1]=='o'){
if(s[i]=='a'){
if(s[i+2]==' '||i+1==n-1) printf("a");
printf("c");
i++;
continue;
}
}
printf("%c",s[i]);
} else {
if(s[i]==' ') {
printf(" ");
flag=1;
} else {
if(s[i+1]=='h') {
if(s[i]=='c') {
printf("i");
i++; continue;
} else if(s[i]=='s') {
printf("u");
i++; continue;
} else if(s[i]=='z') {
printf("v");
i++; continue;
}
} else if(s[i+1]=='i') {
if(s[i]=='a') {
printf("d");
i++; continue;
} else if(s[i]=='e') {
printf("w");
i++; continue;
}
else if(s[i]=='u'){
printf("v");
i++;
continue;
}
} else if(s[i+1]=='n') {
if(s[i]=='a'&&s[i+2]!='g') {
printf("j");
i++; continue;
} else if(s[i]=='a'&&s[i+2]=='g') {
printf("h");
i+=2; continue;
} else if(s[i]=='e'&&s[i+2]!='g') {
printf("f");
i++; continue;
}
else if(s[i]=='e'&&s[i+2]=='g'){
printf("g");
i+=2; continue;
}
else if(s[i]=='i'){
if(s[i+2]=='g'){
printf("k");
i+=2; continue;
}
else {
printf("b");
i+=1; continue;
}
}
else if(s[i]=='o'){
if(s[i+2]=='g'){
i+=2;
printf("s");continue;
}
}
else if(s[i]=='u'){
printf("y");
i++;
continue;
}
} else if(s[i+1]=='u') {
if(s[i]=='i') {
printf("q");
i++; continue;
} else if(s[i]=='o') {
printf("z");
i++; continue;
}
}
else if(s[i+1]=='a'){
if(s[i]=='u'){
if(s[i+2]=='n'){
if(s[i+3]=='g'){
printf("l");
i+=3; continue;
}
else{
printf("r");
i+=2; continue;
}
}
else if(s[i+2]=='i'){
printf("k");
i+=2; continue;
}
else{
printf("x");
i++; continue;
}
}
else if(s[i]=='i'){
if(s[i+2]=='n'){
if(s[i+3]=='g'){
printf("l");
i+=3; continue;
}
else{
printf("m");
i+=2; continue;
}
}
else if(s[i+2]=='o'){
printf("n");
i+=2; continue;
}
else {
printf("x");
i++; continue;
}
}
}
else if(s[i+1]=='e'){
if(s[i]=='i'){
printf("p");
i++; continue;
}
else if(s[i]=='u'){
printf("t");
i++; continue;
}
}
else if(s[i+1]=='o'){
if(s[i]=='u'){
printf("o");
i++; continue;
}
else if(s[i]=='a'){
printf("c");
i++; continue;
}
else if(s[i]=='i'){
if(s[i+2]=='n'&&s[i+3]=='g'){
printf("s");
i+=3; continue;
}
}
}
printf("%c",s[i]);
}
}
}
printf("\n");
}
}
A. Matrix
组合数 好像有优化 先打完表然后直接输出也行
D. Lowbit
势能线段树
#include<bits/stdc++.h>
#define close std::ios::sync_with_stdio(false),cin.tie(0),cout.tie(0)
using namespace std;
typedef long long ll;
const ll MAXN = 3e5+7;
const ll mod = 998244353;
const ll inf = 0x3f3f3f3f;
#define int ll
int a[MAXN];
int lowbit(int x) {
return x&-x;
}
int bitcnt(int x) {
int cnt=0;
while(x) {
x-=lowbit(x);
cnt++;
}
return cnt;
}
struct Info {
int sum,cnt;
};
Info operator +(const Info &a,const Info &b) {
Info c;
c.sum=a.sum+b.sum;
c.sum%=mod;
c.cnt=a.cnt+b.cnt;
return c;
}
struct node {
int lazy;
Info val;
} seg[MAXN<<2];
void up(int id) {
seg[id].val=seg[id<<1].val+seg[id<<1|1].val;
}
void settag(int id,int l,int r,int val) {
seg[id].val.sum*=val;
seg[id].val.sum%=mod;
seg[id].lazy*=val;
seg[id].lazy%=mod;
}
void down(int id,int l,int r) {
if(seg[id].lazy==1) return;
int mid=l+r>>1;
settag(id<<1,l,mid,seg[id].lazy);
settag(id<<1|1,mid+1,r,seg[id].lazy);
seg[id].lazy=1;
}
void build(int id,int l,int r) {
seg[id].lazy=1;
if(l==r) {
seg[id].val.sum=a[l];
seg[id].val.cnt=bitcnt(a[l]);
return;
}
int mid = l+r>>1;
build(id<<1,l,mid);
build(id<<1|1,mid+1,r);
up(id);
}
void change(int id,int l,int r,int pos) {
if(r<pos||l>pos) return;
if(l==r&&l==pos) {
int k=lowbit(seg[id].val.sum);
if(seg[id].val.cnt==1)
seg[id].val.sum*=2,seg[id].val.sum%=mod;
else seg[id].val.sum+=k,seg[id].val.cnt=bitcnt(seg[id].val.sum);
return;
}
int mid=l+r>>1;
down(id,l,r);
change(id<<1,l,mid,pos);
change(id<<1|1,mid+1,r,pos);
up(id);
}
void modify(int id,int l,int r,int ql,int qr) {
if (ql<=l&&r<=qr) {
if(seg[id].val.cnt==r-l+1)
settag(id,l,r,2);
else{
for(int i=l;i<=r;i++) change(id,l,r,i);
}
return;
}
down(id,l,r);
int mid =(l+r) >> 1;
if (qr<=mid)
modify(id <<1,l,mid,ql,qr);
else if (ql>mid)
modify(id<<1|1, mid+1,r,ql,qr);
else {
modify(id<<1,l,mid,ql,qr);
modify(id<<1|1,mid+1,r,ql,qr);
}
up(id);
}
Info query(int id,int l ,int r,int ql,int qr) {
if(ql<=l&&r<=qr) {
return seg[id].val;
}
down(id,l,r);
int mid=l+r>>1;
if(qr<=mid) return query(id<<1,l,mid,ql,qr);
else if(ql>mid) return query(id<<1|1,mid+1,r,ql,qr);
else return query(id<<1,l,mid,ql,qr)+query(id<<1|1,mid+1,r,ql,qr);
}
void solve() {
int n;
cin>>n;
for(int i=1; i<=n; i++) cin>>a[i];
build(1,1,n);
// cout<<"# \n";
// for(int i=1;i<=n;i++) cout<<query(1,1,n,i,i).sum<<" "<<query(1,1,n,i,i).cnt<<"\n";
int q;
cin>>q;
while(q--) {
int op,l,r;
cin>>op>>l>>r;
if(op==1) {
modify(1,1,n,l,r);
} else {
cout<<query(1,1,n,l,r).sum%mod<<"\n";
}
}
}
signed main() {
close;
int t;
cin>>t;
while(t--)
solve();
}
H. Loneliness
J. Transform
7.2021 Jiangxi Provincial Collegiate Programming Contest
赛时过题ABHJKL补题FG
A. Mio visits ACGN Exhibition
从左上角到右下角 有多少条路径的1和0满足要求
dp i j k 现在的位置ij,现在路径的1数量的方案数
滚动数组优化下空间
#include <iostream>
#include <vector>
#include <stack>
#include <map>
#include <set>
#include <queue>
#include <string>
#include <algorithm>
#include <iomanip> //fixed<<setprecision(12)<<
#include <utility> //pair模板
#include <cmath>
#include <random> //mt19937 mtrand(time(0));
#include <time.h>
#define close \
std::ios::sync_with_stdio(false); \
cin.tie(0); \
cout.tie(0)
typedef long long ll;
typedef unsigned long long ull;
const double pi = 3.141592653589793;
const int N = 2e5 + 7;
const ll mod = 998244353;
using namespace std;
ll dp[2][502][1002];
int mp[502][502];
void solve() {
// freopen("data.in.txt","r",stdin);
// freopen("data.out.txt","w",stdout);
int m, n, p, q;
cin >> n >> m >> p >> q;
for (int i = 1; i <= n; i++) {
for (int j = 1; j <= m; j++)
cin >> mp[i][j];
}
if (p + q > n + m) {
cout << "0";
return;
}
for (int i = 1; i <= n; i++) {
for (int j = 1; j <= n; j++) {
if (i == 1 && j == 1) {
dp[i%2][j][mp[i][j]] = 1;
continue;
}
if (mp[i][j]== 0)
for (int k = 0; k < i + j; k++) {
dp[i%2][j][k] = dp[(i - 1)%2][j][k] + dp[i%2][(j - 1)][k];
dp[i%2][j][k]%=mod;
// cout<<dp[i%2][j][k]<<" ";
}
else
for (int k = 0; k < i + j; k++) {
if(k==0) {
dp[i%2][j][k]=0;
continue;
}
dp[i%2][j][k] = dp[(i - 1)%2][j][k - 1] + dp[i%2][(j - 1)][k - 1];
dp[i%2][j][k]%=mod;
// cout<<dp[i%2][j][k]<<" ";
}
}
// cout<<'\n';
}
ll ans=0;
for(int i=q; i<n+m-p; i++) {
ans+=dp[n%2][m][i];
// cout<<dp[n%2][m][i]<<"\n";
ans%=mod;
}
cout << ans<<"\n";
}
int main() {
close;
int t = 1;
// cin>>t;
while (t--) {
solve();
}
return 0;
}
B. Continued Fraction
#include <iostream>
#include <vector>
#include <stack>
#include <map>
#include <set>
#include <queue>
#include <string>
#include <algorithm>
#include <iomanip> //fixed<<setprecision(12)<<
#include <utility> //pair模板
#include <cmath>
#include <random> //mt19937 mtrand(time(0));
#include <time.h>
#define close \
std::ios::sync_with_stdio(false); \
cin.tie(0); \
cout.tie(0)
typedef long long ll;
typedef unsigned long long ull;
const double pi = 3.141592653589793;
const int N = 2e2 + 7;
const ll mod = 200907;
using namespace std;
// int fac[N];
// void init()
// {
// for (int i = 1; i < N; i++)
// {
// fac[i] = fac[i - 1] + i * i;
// }
// }
void solve()
{
int x, y;
vector<int> ans;
cin >> x >> y;
while (1)
{
// cout << x << " " << y << '\n';
ans.push_back(x / y);
x %= y;
if (x == 1)
break;
swap(x, y);
}
ans.push_back(y);
cout << ans.size() - 1 << ' ';
// if (x!=0)
// ans.push_back(y);
// cout << ans.size() - 1 << ' ';
for (auto x : ans)
{
cout << x << " ";
}
cout << '\n';
// freopen("data.in.txt","r",stdin);
// freopen("data.out.txt","w",stdout);
}
int main()
{
// init();
close;
int t = 1;
cin >> t;
while (t--)
{
solve();
}
return 0;
}
H. Hearthstone So Easy
#include <iostream>
#include <vector>
#include <stack>
#include <map>
#include <set>
#include <queue>
#include <string>
#include <algorithm>
#include <iomanip> //fixed<<setprecision(12)<<
#include <utility> //pair模板
#include <cmath>
#include <random> //mt19937 mtrand(time(0));
#include <time.h>
#define close \
std::ios::sync_with_stdio(false); \
cin.tie(0); \
cout.tie(0)
typedef long long ll;
typedef unsigned long long ull;
const double pi = 3.141592653589793;
const int N = 2e2 + 7;
const ll mod = 200907;
using namespace std;
// int fac[N];
// void init()
// {
// for (int i = 1; i < N; i++)
// {
// fac[i] = fac[i - 1] + i * i;
// }
// }
void solve()
{
int n, k, fir = 0;
cin >> n >> k;
// if(n==1)fir=1;
if (n > 1 && n <= 1 + k)
{
fir = 1;
}
puts(fir > 0 ? "pllj" : "freesin");
// freopen("data.in.txt","r",stdin);
// freopen("data.out.txt","w",stdout);
}
int main()
{
// init();
close;
int t = 1;
cin >> t;
while (t--)
{
solve();
}
return 0;
}
J. LRU
二分空间大小 check里面O(n)跑就行了 很快
#include <iostream>
#include <vector>
#include <stack>
#include <map>
#include <set>
#include <queue>
#include <string>
#include <algorithm>
#include <iomanip> //fixed<<setprecision(12)<<
#include <utility> //pair模板
#include <cmath>
#include <random> //mt19937 mtrand(time(0));
#include <time.h>
#define int long long
#define close \
std::ios::sync_with_stdio(false); \
cin.tie(0); \
cout.tie(0)
typedef long long ll;
typedef unsigned long long ull;
const double pi = 3.141592653589793;
const int N = 2e5+ 7;
const ll mod = 200907;
using namespace std;
int n, k, a[N];
queue<pair<int, int>> que;
vector<int> X;
int getX(int x)
{
return lower_bound(X.begin(), X.end(), x) - X.begin();
}
int mp[N], f[N];
bool check(int x)
{
for (int i = 1; i <= n; i++)
f[i] = 0, mp[i] = 0;
int cnt = 0;
while (que.size())
que.pop();
int sz = 0;
for (int i = 1; i <= n; i++)
{
if (f[a[i]] == 1)
{
mp[a[i]] = i;
cnt++;
}
else
{
sz++;
f[a[i]] = 1;
mp[a[i]] = i;
}
que.push({i, a[i]});
while (sz > x)
{
int pos = que.front().first;
int v = que.front().second;
que.pop();
if (pos == mp[v])
{
sz--;
f[v] = 0;
}
}
if (cnt >= k)
return true;
}
if (cnt >= k)
return true;
else
return false;
}
int bs1(int l, int r)
{ // 左偏二分
while (l < r)
{
int mid = l + r >> 1;
// cout << l << " " << r << " " << mid << " ";
if (check(mid))
{
r = mid;
// cout << "true\n";
}
else
{
l = mid + 1;
// cout << "false\n";
}
}
return l;
}
void solve()
{
cin >> n >> k;
X.push_back(-1);
for (int i = 1; i <= n; i++)
{
cin >> a[i];
X.push_back(a[i]);
}
sort(X.begin(), X.end());
X.erase(unique(X.begin(), X.end()), X.end());
for (int i = 1; i <= n; i++)
a[i] = getX(a[i]);
int ans = bs1(1, n + 1);
if (ans != n + 1)
cout << ans << '\n';
else
cout << "cbddl\n";
// freopen("data.in.txt","r",stdin);
// freopen("data.out.txt","w",stdout);
}
signed main()
{
close;
int t = 1;
// cin >> t;
while (t--)
{
solve();
}
return 0;
}
K. Many Littles Make a Mickle
#include <iostream>
#include <vector>
#include <stack>
#include <map>
#include <set>
#include <queue>
#include <string>
#include <algorithm>
#include <iomanip> //fixed<<setprecision(12)<<
#include <utility> //pair模板
#include <cmath>
#include <random> //mt19937 mtrand(time(0));
#include <time.h>
#define close \
std::ios::sync_with_stdio(false); \
cin.tie(0); \
cout.tie(0)
typedef long long ll;
typedef unsigned long long ull;
const double pi = 3.141592653589793;
const int N = 2e2 + 7;
const ll mod = 200907;
using namespace std;
int fac[N];
void init()
{
for (int i = 1; i < N; i++)
{
fac[i] = fac[i - 1] + i * i;
}
}
void solve()
{
int k, m;
cin >> k >> m;
cout << fac[k] * m << '\n';
// freopen("data.in.txt","r",stdin);
// freopen("data.out.txt","w",stdout);
}
int main()
{
init();
close;
int t = 1;
cin >> t;
while (t--)
{
solve();
}
return 0;
}
L. It Rains Again
差分数组 找有多少个点覆盖了
#include <iostream>
#include <vector>
#include <stack>
#include <map>
#include <set>
#include <queue>
#include <string>
#include <algorithm>
#include <iomanip> //fixed<<setprecision(12)<<
#include <utility> //pair模板
#include <cmath>
#include <random> //mt19937 mtrand(time(0));
#include <time.h>
#define close \
std::ios::sync_with_stdio(false); \
cin.tie(0); \
cout.tie(0)
typedef long long ll;
typedef unsigned long long ull;
const double pi = 3.141592653589793;
const int N = 2e5 + 7;
const ll mod = 200907;
using namespace std;
int suf[N];
int pre[N];
void solve()
{
// freopen("data.in.txt","r",stdin);
// freopen("data.out.txt","w",stdout);
int n;
cin >> n;
for (int i = 1; i <= n; i++)
{
int a, b, c, d;
cin >> a >> b >> c >> d;
suf[a]++;
suf[c]--;
}
for (int i = 1; i <= 100007; i++)
{
pre[i] = pre[i - 1] + suf[i];
}
int ans = 0;
for (int i = 1; i <= 100000; i++)
{
if (pre[i] > 0)
{
ans++;
// cout << "$ " << i << "\n";
}
}
cout << ans;
}
int main()
{
close;
int t = 1;
// cin>>t;
while (t--)
{
solve();
}
return 0;
}
F. Four Column Hanoi Tower
打表 然后观察发现 第一次+2 第二次+2
+4+4+4+8+8+8+8这样的 最后要输出一个大数
用py写的
arr = []
ans =[1]
tmp=1
for i in range(1,600):
tmp*=2
for j in range(0,i+1):
arr.append(tmp)
for i in range(1,100000):
ans.append(ans[i-1]+arr[i-1])
t=int(input())
for i in range(0,t):
k=int(input())
print(ans[k-1])
G. Magic Number Group
找最多的连续的因数出现的次数 就像众数
那就用莫队
#include<bits/stdc++.h>
#define close std::ios::sync_with_stdio(false),cin.tie(0),cout.tie(0)
using namespace std;
typedef long long ll;
const ll MAXN = 1e6+700;
const ll mod = 1e9+7;
const ll inf = 0x3f3f3f3f;
#define int ll
bool isPri[MAXN]={1,1};//质数0
int prime[MAXN]; int cnt=0;
void getPrime(){
for(int i=2;i<=MAXN-5;i++){
if(isPri[i]==0) prime[++cnt]=i;
for(int j=1;j<=cnt;j++){
if(i*prime[j]>MAXN-5) break;
isPri[i*prime[j]]=1;
if(i%prime[j]==0) break;
}
}
}
struct node{
int L,R,k;
}q[MAXN];
int pos[MAXN];
int a[MAXN];
int res[MAXN];
int ans=0,mx; int n,m;
int coun[MAXN],ct[MAXN];
vector<int> vec[MAXN];
void init(){
for(int i=1;i<=n;i++){
int tmp=a[i];
for(int j=1;j<cnt;j++){
if(j*j>a[i]) break;
if(tmp%prime[j]==0) vec[i].push_back(prime[j]);
while(tmp%prime[j]==0) tmp/=prime[j];
if(tmp==1) break;
}
if(tmp!=1) vec[i].push_back(tmp);
}
}
bool cmp(node a,node b){
if(pos[a.L]!=pos[b.L]) return pos[a.L]<pos[b.L];
if(pos[a.L]&1) return a.R>b.R;
return a.R<b.R;
}
void add(int x){
for(auto &it:vec[x]){
ct[coun[it]]--;
coun[it]++;
ct[coun[it]]++;
if(coun[it]>ans) ans=coun[it];
}
}
void del(int x){
for(auto &it:vec[x]){
ct[coun[it]]--;
coun[it]--;
ct[coun[it]]++;
}
if(ct[ans]==0&&ans!=0) ans--;
}
void solve(){
ans=0;
cin>>n>>m;
int B=n/sqrt(m)+1;
for(int i=1;i<=n;i++) cin>>a[i];
init();
for(int i=1;i<=m;i++){
cin>>q[i].L>>q[i].R;
q[i].k=i;
}
for(int i=1;i<=n;i++){
pos[i]=(i-1)/B+1;
}
sort(q+1,q+1+m,cmp);
int L=1,R=0;
for(int i=1;i<=m;i++){
while(L>q[i].L) add(--L);
while(R<q[i].R) add(++R);
while(L<q[i].L) del(L++);
while(R>q[i].R) del(R--);
res[q[i].k]=ans;
}
while(L<=R) del(L++);
for(int i=1;i<=m;i++) cout<<res[i]<<"\n";
for(int i=1;i<=n;i++) vec[i].clear();
}
signed main(){
close;
getPrime();
int t;cin>>t;
while(t--)
solve();
}
8.2019-2020 ACM-ICPC Pacific Northwest Regional Contest (Div. 1)
赛时过题ACDEM 补题B
A Radio Prize
换根板子 需要推出一个能换的式子
#include <iostream>
#include <vector>
#include <stack>
#include <map>
#include <set>
#include <queue>
#include <string>
#include <algorithm>
#include <iomanip> //fixed<<setprecision(12)<<
#include <utility> //pair模板
#include <cmath>
#include <random> //mt19937 mtrand(time(0));
#include <time.h>
#define close \
std::ios::sync_with_stdio(false); \
cin.tie(0); \
cout.tie(0)
typedef long long ll;
typedef unsigned long long ull;
const double pi = 3.141592653589793;
const int N = 2e5 + 7;
const ll mod = 998244353;
using namespace std;
#define int ll
int dp[2][N]; // sum path lenth
// int dp1[N];
// sz path lenth
int f[2][N];
int sum[N], sz[N];
int a[N];
vector<pair<int, int>> adj[N];
void dfs_down(int u, int fa)
{
sz[u] = 1;
sum[u] = a[u];
int faw = 1;
for (auto &it : adj[u])
{
int v = it.first, w = it.second;
if (v == fa)
{
continue;
}
dfs_down(v, u);
sz[u] += sz[v];
sum[u] += sum[v];
dp[0][u] += dp[0][v] + sum[v] * w;
dp[1][u] += dp[1][v] + sz[v] * w;
}
}
void dfs_up(int u, int fa)
{
for (auto &it : adj[u])
{
int v = it.first, w = it.second;
if (v == fa)
continue;
f[0][v] = f[0][u] + (sum[1] - 2 * sum[v]) * w;
f[1][v] = f[1][u] + (sz[1] - 2 * sz[v]) * w;
dfs_up(v, u);
}
}
void solve()
{
// freopen("data.in.txt","r",stdin);
// freopen("data.out.txt","w",stdout);
int n;
cin >> n;
for (int i = 1; i <= n; i++)
cin >> a[i];
for (int i = 1; i < n; i++)
{
int u, v, w;
cin >> u >> v >> w;
adj[u].push_back({v, w});
adj[v].push_back({u, w});
}
dfs_down(1, 0);
f[1][1] = dp[1][1];
f[0][1] = dp[0][1];
// cout<<"# "<<dp[1][1]<<' '<<dp[0][1]<<"\n";
dfs_up(1, 0);
for (int i = 1; i <= n; i++)
{
cout << f[1][i] * a[i] + f[0][i] << "\n";
}
}
signed main()
{
close;
int t = 1;
// cin>>t;
while (t--)
{
solve();
}
return 0;
}
C Coloring Contention
找最大颜色变换的次数 那从末尾开始dfs 然后找最短路径就行了
#include <iostream>
#include <vector>
#include <stack>
#include <map>
#include <set>
#include <queue>
#include <string>
#include <algorithm>
#include <iomanip> //fixed<<setprecision(12)<<
#include <utility> //pair模板
#include <cmath>
#include <random> //mt19937 mtrand(time(0));
#include <time.h>
#define close \
std::ios::sync_with_stdio(false); \
cin.tie(0); \
cout.tie(0)
typedef long long ll;
typedef unsigned long long ull;
const double pi = 3.141592653589793;
const int N = 2e5 + 7;
const ll mod = 998244353;
using namespace std;
vector<int> adj[N];
int d[N], vis[N];
queue<int> que;
void solve()
{
// freopen("data.in.txt","r",stdin);
// freopen("data.out.txt","w",stdout);
int n, m;
cin >> n >> m;
for(int i=1;i<=n;i++) d[i]=1e9+7;
for (int i = 1; i <= m; i++)
{
int u, v;
cin >> u >> v;
adj[u].push_back(v);
adj[v].push_back(u);
}
d[n] = 0;
vis[n] = 1;
que.push(n);
while (que.size())
{
int u = que.front();
que.pop();
for (auto v : adj[u])
{
if (d[v] > d[u] + 1)
{
d[v] = d[u] + 1;
}
if (!vis[v])
{
que.push(v);
vis[v] = 1;
}
}
}
cout << d[1]-1;
}
signed main()
{
close;
int t = 1;
// cin>>t;
while (t--)
{
solve();
}
return 0;
}
D Dividing by Two
贪心 不停整除 小了就加
#include <iostream>
#include <vector>
#include <stack>
#include <map>
#include <set>
#include <queue>
#include <string>
#include <algorithm>
#include <iomanip> //fixed<<setprecision(12)<<
#include <utility> //pair模板
#include <cmath>
#include <random> //mt19937 mtrand(time(0));
#include <time.h>
#define close \
std::ios::sync_with_stdio(false); \
cin.tie(0); \
cout.tie(0)
typedef long long ll;
typedef unsigned long long ull;
const double pi = 3.141592653589793;
const int N = 2e5 + 7;
const ll mod = 998244353;
using namespace std;
ll a, b;
void solve()
{
// freopen("data.in.txt","r",stdin);
// freopen("data.out.txt","w",stdout);
cin >> a >> b;
ll ans = 0;
while (a > b)
{
if (a % 2 == 0)
a /= 2;
else
a++;
ans++;
}
ans += b - a;
cout << ans << endl;
}
signed main()
{
close;
int t = 1;
// cin>>t;
while (t--)
{
solve();
}
return 0;
}
E Rainbow Strings
#include <iostream>
#include <vector>
#include <stack>
#include <map>
#include <set>
#include <queue>
#include <string>
#include <algorithm>
#include <iomanip> //fixed<<setprecision(12)<<
#include <utility> //pair模板
#include <cmath>
#include <random> //mt19937 mtrand(time(0));
#include <time.h>
#define close \
std::ios::sync_with_stdio(false); \
cin.tie(0); \
cout.tie(0)
typedef long long ll;
typedef unsigned long long ull;
const double pi = 3.141592653589793;
const int N = 2e5 + 7;
const ll mod = 11092019;
using namespace std;
string s;
int cnt[30];
void solve()
{
string s;
cin >> s;
for (auto x : s)
{
cnt[x - 'a']++;
}
ll ans = 1;
for (int i = 0; i < 26; i++)
{
ans *= (cnt[i] + 1);
ans %= mod;
}
cout << ans << '\n';
// freopen("data.in.txt","r",stdin);
// freopen("data.out.txt","w",stdout);
cin >> s;
}
signed main()
{
close;
int t = 1;
// cin>>t;
while (t--)
{
solve();
}
return 0;
}
M Maze Connect
找菱形的个数和由.开始搜索的连通块数量
#include <iostream>
#include <vector>
#include <stack>
#include <map>
#include <set>
#include <queue>
#include <string>
#include <algorithm>
#include <iomanip> //fixed<<setprecision(12)<<
#include <utility> //pair模板
#include <cmath>
#include <random> //mt19937 mtrand(time(0));
#include <time.h>
#define close \
std::ios::sync_with_stdio(false); \
cin.tie(0); \
cout.tie(0)
typedef long long ll;
typedef unsigned long long ull;
const double pi = 3.141592653589793;
const int N = 1e3 + 7;
const ll mod = 998244353;
using namespace std;
int row, col;
char mp[N][N];
int vis[N][N];
int dx[4] = {-1, 0, 0, 1};
int dy[4] = {0, -1, 1, 0};
int ex[4] = {-1, 1, -1, 1};
int ey[4] = {-1, -1, 1, 1};
void solve()
{
// freopen("data.in.txt","r",stdin);
// freopen("data.out.txt","w",stdout);
cin >> row >> col;
int ans = 0;
for (int i = 1; i <= row; i++)
for (int j = 1; j <= col; j++)
cin >> mp[i][j];
if (row == 1)
{
for (int i = 1; i <= col; i++)
if (mp[1][i] != '.')
ans++;
cout << ans << endl;
return;
}
if (col == 1)
{
for (int i = 1; i <= row; i++)
if (mp[i][1] != '.')
ans++;
cout << ans << endl;
return;
}
// if(row==1&&col==1&&mp[1][1]!='.')cout<<1<<'\n';
// if (mp[1][2] == '\\')
// cout << 'k' << endl;
for (int i = 1; i <= row; i++)
for (int j = 1; j <= col; j++)
{
if (mp[i][j] == '.' && vis[i][j] == 0)
{
bool flag = true;
queue<pair<int, int>> q;
q.push({i, j});
while (q.size())
{
int x = q.front().first, y = q.front().second;
q.pop();
// if (i == 2 && j == 2)
// cout << x << ' ' << y << endl;
if (x <= 1 || y <= 1 || x >= row || y >= col)
{
flag = false;
continue;
}
if (vis[x][y] == 1)
continue;
vis[x][y] = 1;
for (int i = 0; i < 4; i++)
{
int xx = x + dx[i];
int yy = y + dy[i];
if (mp[xx][yy] != '\\' && mp[xx][yy] != '/')
q.push({xx, yy});
}
if (mp[x - 1][y - 1] != '\\' && mp[x - 1][y - 1] != '/')
if (mp[x][y - 1] != '/')
q.push({x - 1, y - 1});
if (mp[x - 1][y + 1] != '\\' && mp[x - 1][y + 1] != '/')
if (mp[x][y + 1] != '\\')
q.push({x - 1, y + 1});
if (mp[x + 1][y - 1] != '\\' && mp[x + 1][y - 1] != '/')
if (mp[x][y - 1] != '\\')
q.push({x + 1, y - 1});
if (mp[x + 1][y + 1] != '\\' && mp[x + 1][y + 1] != '/')
if (mp[x][y + 1] != '/')
q.push({x + 1, y + 1});
}
if (flag)
ans++;
}
}
for (int i = 1; i < row; i++)
for (int j = 1; j < col; j++)
if (mp[i][j] == '/' && mp[i + 1][j] == '\\' && mp[i][j + 1] == '\\' && mp[i + 1][j + 1] == '/')
ans++;
cout << ans << endl;
}
signed main()
{
close;
int t = 1;
// cin>>t;
while (t--)
{
solve();
}
return 0;
}
B Perfect Flush
单调栈板子题 没看出来
9.The 13th Chinese Northeast Collegiate Programming Contest
赛时过题BCEGHJ 补题DF
B. Balanced Diet
每个糖果选的个数不能少于limi或者不选
S为总的贡献值 C为数量最大的种类 的数量
求S/C最大
前缀和求出每种糖果在有i个时的值 然后遍历i
记得break 复杂度为O(n)
#include <iostream>
#include <vector>
#include <stack>
#include <map>
#include <set>
#include <queue>
#include <string>
#include <algorithm>
#include <iomanip> //fixed<<setprecision(12)<<
#include <utility> //pair模板
#include <cmath>
#include <random> //mt19937 mtrand(time(0));
#include <time.h>
#define close \
std::ios::sync_with_stdio(false); \
cin.tie(0); \
cout.tie(0)
typedef long long ll;
typedef unsigned long long ull;
#define int ll
const double pi = 3.141592653589793;
const int N = 2e5 + 7;
const ll mod = 998244353;
using namespace std;
int l[N];
int prel[N];
vector<int> pre[N];
struct node{
int len;
int id;
}Node[N];
bool bj(node a,node b){
return a.len>b.len;
}
void solve()
{
int n,m;cin>>n>>m;
for(int i=1;i<=m;i++){
cin>>l[i];
}
for(int i=1;i<=m;i++){
Node[i].id=i;
}
for(int i=1;i<=n;i++){
int x,ty;cin>>x>>ty;
pre[ty].push_back(x);
Node[ty].len++;
}
prel[0]=m;
for(int i=1;i<=m;i++){
sort(pre[i].begin(),pre[i].end(),greater<int>());
for(int j=1;j<min(l[i],Node[i].len);j++){
pre[i][j]=pre[i][j]+pre[i][j-1];
}
}
for(int i=1;i<=m;i++){
prel[Node[i].len+1]--;
}
for(int i=1;i<=n;i++) prel[i]=prel[i-1]+prel[i];
sort(Node+1,Node+m+1,bj);
double ans=0.0;
int ansx,ansy;int fz=0;
for(int c=1;c<=n;c++){
for(int now=1;now<=prel[c];now++){
if(c<l[Node[now].id]) continue;
fz+=pre[Node[now].id][c-1];
}
if(fz==0) continue;
if(fz*1.0/c>ans){
ans=fz*1.0/c;
ansx=fz;
ansy=c;
}
}
int k=__gcd(ansx,ansy);
ansx/=k;
ansy/=k;
cout<<ansx<<"/"<<ansy<<"\n";
for(int i=1;i<=n;i++) prel[i]=0;
for(int i=1;i<=m;i++) {
pre[i].clear();
Node[i].len=0;
}
}
signed main()
{
close;
int t = 1;
cin>>t;
while (t--)
{
solve();
}
return 0;
}
C. Line-line Intersection
求有交点的线段的个数 做了非正解 不太好 精度要开-22
#include <iostream>
#include <vector>
#include <stack>
#include <map>
#include <set>
#include <queue>
#include <string>
#include <algorithm>
#include <iomanip> //fixed<<setprecision(12)<<
#include <utility> //pair模板
#include <cmath>
#include <random> //mt19937 mtrand(time(0));
#include <time.h>
#define close \
std::ios::sync_with_stdio(false); \
cin.tie(0); \
cout.tie(0)
typedef long long ll;
typedef unsigned long long ull;
const double pi = 3.141592653589793;
const int N = 2e5 + 7;
const ll inf = 0x3f3f3f3f;
const ll mod = 998244353;
const double eps = 1e-22;
using namespace std;
#define int ll
#define double long double
struct node
{
double k;
double b;
} edge[N];
bool bj(node a, node b)
{
if (fabs(a.k - b.k) <= eps)
{
return a.b < b.b;
}
else
return a.k < b.k;
}
void solve()
{
// freopen("data.in.txt","r",stdin);
// freopen("data.out.txt","w",stdout);
int n;
cin >> n;
for (int i = 1; i <= n; i++)
{
int ax, ay, bx, by;
cin >> ax >> ay >> bx >> by;
if (bx != ax)
edge[i].k = (by - ay) * 1.0 / (bx - ax) ,edge[i].b = ay - edge[i].k * ax;
else
edge[i].k = inf * 1.0,edge[i].b=ax;
}
sort(edge + 1, edge + n + 1, bj);
ll ans = n * (n - 1) / 2, sav = 1, tol = 1, tmp = 0;
for (int i = 2; i <= n; i++)
{
if (fabs(edge[i].k - edge[i - 1].k) >= eps)
{
tmp += sav * (sav - 1) / 2;
// cerr << tol << " " << tmp << '\n';
ans -= tol * (tol - 1) / 2 - tmp;
// cout << "ans:" << ans << '\n';
tol = 1;
sav = 1;
tmp = 0;
}
else if (fabs(edge[i].k - edge[i - 1].k) < eps && fabs(edge[i].b - edge[i - 1].b) < eps)
{
// cout<<"had ";
tol++;
sav++;
}
else
{
// cout << "sav:" << sav << '\n';
tmp += sav * (sav - 1) / 2;
sav = 1;
tol++;
}
}
tmp += sav * (sav - 1) / 2;
// cerr << tol << " " << sav << '\n';
ans -= tol * (tol - 1) / 2 - tmp;
cout << ans << "\n";
}
signed main()
{
close;
int t = 1;
cin >> t;
while (t--)
{
solve();
}
return 0;
}
E. Minimum Spanning Tree
把树的边看成点 然后建图 最小生成树
每个子节点里面一层都是完全图 完全图里所有边都取一次 然后最小的取n-1次就行了
#include <iostream>
#include <vector>
#include <stack>
#include <map>
#include <set>
#include <queue>
#include <string>
#include <algorithm>
#include <iomanip> //fixed<<setprecision(12)<<
#include <utility> //pair模板
#include <cmath>
#include <random> //mt19937 mtrand(time(0));
#include <time.h>
#define close \
std::ios::sync_with_stdio(false); \
cin.tie(0); \
cout.tie(0)
typedef long long ll;
typedef unsigned long long ull;
const double pi = 3.141592653589793;
const int N = 2e5 + 7;
const ll mod = 998244353;
using namespace std;
#define int long long
vector<pair<int, int>> G[N];
int d[N];
void solve()
{
int n;
cin >> n;
for (int i = 1; i <= n; i++)
{
G[i].clear();
d[i] = 0;
}
for (int i = 1; i < n; i++)
{
int x, y, w;
cin >> x >> y >> w;
G[x].push_back({y, w});
G[y].push_back({x, w});
d[x]++;
d[y]++;
}
int ans = 0;
for (int i = 1; i <= n; i++)
{
int sum = 0, minn = 1000000000000000;
if (d[i] == 1)
continue;
if (d[i] == 2)
{
for (auto it : G[i])
{
int x = it.first, y = it.second;
sum += y;
minn = min(minn, y);
}
ans += sum;
continue;
}
for (auto it : G[i])
{
int x = it.first, y = it.second;
sum += y;
minn = min(minn, y);
}
sum += minn * (d[i] - 2);
ans += sum;
}
cout << ans << '\n';
// freopen("data.in.txt","r",stdin);
// freopen("data.out.txt","w",stdout);
}
signed main()
{
close;
int t = 1;
cin >> t;
while (t--)
{
solve();
}
return 0;
}
G. Radar Scanner
二分写的 找x和y让大家最小的区间
#include <iostream>
#include <vector>
#include <stack>
#include <map>
#include <set>
#include <queue>
#include <string>
#include <algorithm>
#include <iomanip> //fixed<<setprecision(12)<<
#include <utility> //pair模板
#include <cmath>
#include <random> //mt19937 mtrand(time(0));
#include <time.h>
#define close \
std::ios::sync_with_stdio(false); \
cin.tie(0); \
cout.tie(0)
typedef long long ll;
typedef unsigned long long ull;
const double pi = 3.141592653589793;
const int N = 2e5 + 7;
const ll inf = 1e9;
const ll mod = 998244353;
using namespace std;
int n;
struct rec
{
ll x1, y1, x2, y2;
} rc[N];
struct qujian
{
ll l, r;
} qj[N];
int find(ll pos)
{
// cout << pos << endl;
// for (int i = 1; i <= n; i++)
// cout << qj[i].l << ' ' << qj[i].r << endl;
int cntl = 0, cntr = 0;
for (int i = 1; i <= n; i++)
{
if (qj[i].r < pos)
cntl++;
else if (pos < qj[i].l)
cntr++;
}
// cout << cntl << ' ' << cntr << endl;
if (cntl >= cntr)
return -1;
else
return 1;
}
ll count()
{
ll l = 0, r = inf + 10, mid;
while (l <= r)
{
mid = l + r >> 1;
int op = find(mid);
// cout << op << endl;
// if (op == 0)
// break;
if (op == -1)
r = mid - 1;
else
l = mid + 1;
// cout << l << ' ' << r << endl;
}
// cout << mid << endl;
// cout << l << endl;
ll ans = 0, mn;
for (int i = 1; i <= n; i++)
{
if (qj[i].r < r)
ans += r - qj[i].r;
else if (r < qj[i].l)
ans += qj[i].l - r;
}
mn = ans;
ans = 0;
for (int i = 1; i <= n; i++)
{
if (qj[i].r < l)
ans += l - qj[i].r;
else if (l < qj[i].l)
ans += qj[i].l - l;
}
mn = min(mn, ans);
return mn;
}
void solve()
{
// freopen("data.in.txt","r",stdin);
// freopen("data.out.txt","w",stdout);
cin >> n;
for (int i = 1; i <= n; i++)
cin >> rc[i].x1 >> rc[i].y1 >> rc[i].x2 >> rc[i].y2;
for (int i = 1; i <= n; i++)
qj[i].l = rc[i].x1, qj[i].r = rc[i].x2;
ll ans = 0;
ans += count();
for (int i = 1; i <= n; i++)
qj[i].l = rc[i].y1, qj[i].r = rc[i].y2;
ans += count();
cout << ans << endl;
}
signed main()
{
close;
int t = 1;
cin >> t;
while (t--)
{
solve();
}
return 0;
}
H. Skyscraper
建造大楼 会有操作抬升楼
最小建造次数的算法是所有上升 的长度的和
就是对每个点求它和上一个点的差 大于0有贡献
抬升区间(L-R) 只会改变L点和R+1点的贡献
用树状数组维护新数组和贡献
#include<bits/stdc++.h>
#include <iostream>
#include <vector>
#include <stack>
#include <map>
#include <set>
#include <queue>
#include <string>
#include <algorithm>
#include <iomanip> //fixed<<setprecision(12)<<
#include <utility> //pair模板
#include <cmath>
#include <random> //mt19937 mtrand(time(0));
#include <time.h>
#define close \
std::ios::sync_with_stdio(false); \
cin.tie(0); \
cout.tie(0)
typedef long long ll;
typedef unsigned long long ull;
const double pi = 3.141592653589793;
const int N = 4e5 + 7;
const ll mod = 998244353;
using namespace std;
#define int ll
int t[N],a[N],t2[N];
int lowbit(int x){
return x&-x;
}
ll getsum(int x){
ll sum=0;
while(x){
sum+=t[x];
x-=lowbit(x);
}
return sum;
}
void addv(int x,int val){
while(x<=100005){
t[x]+=val;
x+=lowbit(x);
}
}
ll getsum2(int x){
ll sum=0;
while(x){
sum+=t2[x];
x-=lowbit(x);
}
return sum;
}
void addv2(int x,int val){
while(x<=100005){
t2[x]+=val;
x+=lowbit(x);
}
}
void solve()
{
// freopen("data.in.txt","r",stdin);
// freopen("data.out.txt","w",stdout);
memset(t,0,sizeof(t));
memset(t2,0,sizeof(t));
int n,m;cin>>n>>m;
for(int i=1;i<=n;i++){
cin>>a[i];
}
for(int i=1;i<=n;i++){
if(a[i]-a[i-1]>0) addv(i,a[i]-a[i-1]);
}
while(m--){
int op;cin>>op;
if(op==1){
int l,r,x;cin>>l>>r>>x;
addv2(l,x);
addv2(r+1,-x);
if(a[l]+getsum2(l)-a[l-1]-getsum2(l-1)>0){
int tmp = getsum(l)-getsum(l-1);
addv(l,a[l]+getsum2(l)-a[l-1]-getsum2(l-1)-tmp);
}
if(a[r]+getsum2(r)-a[r+1]-getsum2(r+1)>0){
int tmp=getsum(r+1)-getsum(r);
addv(r+1,tmp*-1);
}
else{
int tmp=getsum(r+1)-getsum(r);
addv(r+1,tmp*-1);
addv(r+1,a[r+1]+getsum2(r+1)-(a[r]+getsum2(r)));
}
}
else {
int l,r;cin>>l>>r;
cout<<a[l]+getsum2(l)+getsum(r)-getsum(l)<<"\n";
}
// for(int i=1;i<=n;i++){
// cout<<a[i]+getsum2(i)<<" ";
// }
// cout<<'\n';
}
}
signed main()
{
close;
int t = 1;
cin>>t;
while (t--)
{
solve();
}
return 0;
}
J. Time Limit
签到 找tle时间
#include <iostream>
#include <vector>
#include <stack>
#include <map>
#include <set>
#include <queue>
#include <string>
#include <algorithm>
#include <iomanip> //fixed<<setprecision(12)<<
#include <utility> //pair模板
#include <cmath>
#include <random> //mt19937 mtrand(time(0));
#include <time.h>
#define close \
std::ios::sync_with_stdio(false); \
cin.tie(0); \
cout.tie(0)
typedef long long ll;
typedef unsigned long long ull;
const double pi = 3.141592653589793;
const int N = 2e5 + 7;
const ll mod = 998244353;
using namespace std;
void solve()
{
int n;
cin >> n;
vector<int> a(n + 10);
for (int i = 1; i <= n; i++)
{
cin >> a[i];
}
int ans = a[1] * 3;
for (int i = 2; i <= n; i++)
{
ans = max(ans, a[i] + 1);
}
if (ans % 2)
cout << ans + 1 << '\n';
else
cout << ans << '\n';
// freopen("data.in.txt","r",stdin);
// freopen("data.out.txt","w",stdout);
}
signed main()
{
close;
int t = 1;
cin >> t;
while (t--)
{
solve();
}
return 0;
}
D. Master of Data Structure
场上还在瞎写
2000次询问 是个虚树题 建虚树暴力跑时间完全够
#include<bits/stdc++.h>
#define close std::ios::sync_with_stdio(false),cin.tie(0),cout.tie(0)
using namespace std;
typedef long long ll;
const ll MAXN = 5e5+7;
const ll mod = 1e9+7;
const ll inf = 0x3f3f3f3f;
#define int ll
vector<array<int,4> > Q;
vector<int> adj[MAXN],vg[MAXN];
int par[MAXN][20],dep[MAXN];
int f[MAXN];
int w[MAXN];//u点向上的权值
int a[MAXN];
int d[MAXN];
//par[u][i]代表点u的祖先中 深度为max(1,dep[u]-2^i)是谁
int in[MAXN],out[MAXN],tim=0;
void dfs(int u,int fa) {
dep[u]=dep[fa]+1;
par[u][0]=fa;
for(int i=1; i<20; ++i) {
par[u][i]=par[par[u][i-1]][i-1];
}
for(auto &v:adj[u]) {
if(v==fa) continue;
dfs(v,u);
}
}
int getLCA(int u,int v) {
if(dep[u]<dep[v]) swap(u,v);
for(int i=19; i>=0; --i) {
if(dep[par[u][i]]>=dep[v]) u=par[u][i];
}
if(u==v) return u;
for(int i=19; i>=0; i--) {
if(par[u][i]!=par[v][i]) {
u=par[u][i];
v=par[v][i];
}
}
return par[u][0];
}
void init(int u,int fa) {
in[u]=++tim;
for(auto v:adj[u]) {
if(v==fa) continue;
init(v,u);
}
out[u]=tim;
}
int isp(int u, int v) {
return in[u] <= in[v] && out[v] <= out[u];
}
bool cmp(int u, int v) {
return in[u] < in[v];
}
void build(vector<int>&node) {
sort(node.begin(), node.end(), cmp);
set<int>node_st;
for (int x : node)node_st.insert(x);
for (int i = 1; i < node.size(); i++)node_st.insert(getLCA(node[i - 1], node[i]));
node.clear();
for (int x : node_st)node.push_back(x);
sort(node.begin(), node.end(), cmp);
vector<int> st;
for (int v : node) {
while (!st.empty() && !isp(st.back(), v))
st.pop_back();
if (!st.empty()) {
vg[st.back()].push_back(v);
}
st.push_back(v);
}
}
void dfs2(int u,int fa) {
d[u]=d[fa]+1;
f[u]=fa;
for(auto &v:vg[u]) {
if(v==fa) continue;
dfs2(v,u);
}
}
//node.push_back(1)
//build(node);
void work(int u,int v,int k,int op) {
int ans=0;
if(op==1) {
while(u!=v) {
assert(u&&v);
if(d[u]>d[v]) {
a[u]+=k;
w[u]+=k;
u=f[u];
} else {
a[v]+=k;
w[v]+=k;
v=f[v];
}
}
a[u]+=k;
} else if(op==2) {
while(u!=v) {
assert(u&&v);
if(d[u]>d[v]) {
a[u]^=k;
w[u]^=k;
u=f[u];
} else {
a[v]^=k;
w[v]^=k;
v=f[v];
}
}
a[u]^=k;
} else if(op==3) {
while(u!=v) {
assert(u&&v);
if(d[u]>d[v]) {
if(a[u]>=k)
a[u]-=k;
if(w[u]>=k)
w[u]-=k;
u=f[u];
} else {
if(a[v]>=k)
a[v]-=k;
if(w[v]>=k)
w[v]-=k;
v=f[v];
}
}
if(a[u]>=k) a[u]-=k;
} else if(op==4) {
while(u!=v) {
assert(u&&v);
if(d[u]>d[v]) {
ans+=(dep[u]-dep[f[u]]-1)*w[u]+a[u];
u=f[u];
} else {
ans+=(dep[v]-dep[f[v]]-1)*w[v]+a[v];
v=f[v];
}
}
ans+=a[u];
cout<<ans<<"\n";
} else if(op==5) {
while(u!=v) {
assert(u&&v);
if(d[u]>d[v]) {
ans^=a[u];
if((dep[u]-dep[f[u]]-1)%2==1) ans^=w[u];
u=f[u];
} else {
ans^=a[v];
if((dep[v]-dep[f[v]]-1)%2==1) ans^=w[v];
v=f[v];
}
}
ans^=a[u];
cout<<ans<<"\n";
} else if(op==6) {
int mins=a[u],maxs=a[u];
while(u!=v) {
assert(u&&v);
if(d[u]>d[v]) {
mins=min(mins,a[u]);
if((dep[u]-dep[f[u]]-1))
mins=min(mins,w[u]);
maxs=max(maxs,a[u]);
if((dep[u]-dep[f[u]]-1))
maxs=max(maxs,w[u]);
u=f[u];
} else {
mins=min(mins,a[v]);
if((dep[v]-dep[f[v]]-1))
mins=min(mins,w[v]);
maxs=max(maxs,a[v]);
if((dep[v]-dep[f[v]]-1))
maxs=max(maxs,w[v]);
v=f[v];
}
}
mins=min(mins,a[u]);
maxs=max(maxs,a[u]);
ans=maxs-mins;
cout<<ans<<'\n';
} else if(op==7) {
ans=inf;
while(u!=v) {
assert(u&&v);
if(d[u]>d[v]) {
ans=min(ans,abs(a[u]-k));
if((dep[u]-dep[f[u]]-1))
ans=min(ans,abs(w[u]-k));
u=f[u];
} else {
ans=min(ans,abs(a[v]-k));
if((dep[v]-dep[f[v]]-1))
ans=min(ans,abs(w[v]-k));
v=f[v];
}
}
ans=min(ans,abs(a[u]-k));
cout<<ans<<"\n";
}
}
void solve() {
int n,q;
cin>>n>>q;
vector<int> node;
Q.clear();
tim=0;
for(int i=1; i<=n; i++) {
for(int j=0; j<20; j++) par[i][j]=0;
adj[i].clear();
vg[i].clear();
a[i]=0;
w[i]=0;
dep[i]=0;
d[i]=0;
}
for(int i=1; i<n; i++) {
int u,v;
cin>>u>>v;
adj[u].push_back(v);
adj[v].push_back(u);
}
dfs(1,0);
init(1,0);
set<int> sta;
for(int i=1; i<=q; i++) {
int op;
cin>>op;
if(op==1||op==2||op==3||op==7) {
int u,v,k;
cin>>u>>v>>k;
Q.push_back({op,u,v,k});
sta.insert(u);
sta.insert(v);
} else {
int u,v;
cin>>u>>v;
Q.push_back({op,u,v,0});
sta.insert(u);
sta.insert(v);
}
}
sta.insert(1);
assert(sta.size() <= 6000);
for(auto &it:sta) node.push_back(it);
build(node);
dfs2(1,0);
for(int i=0; i<q; i++) {
int op=Q[i][0],u=Q[i][1],v=Q[i][2],k=Q[i][3];
work(u,v,k,op);
// cout<<"TEST : \n";
// for(int i=1; i<=n; i++) {
// cout<<"a: "<<a[i]<<" w: "<<w[i]<<"\n";
// }
}
}
signed main() {
close;
int t;
cin>>t;
while(t--)
solve();
}
F. Mini-game Before Contest
图上博弈 写SG函数一样的操作
10.The 10th Shandong Provincial Collegiate Programming Contest
赛时过题ACDFLM 补题EHIK
A. Calandar
给出日历规定 算新日历
#include <iostream>
#include <vector>
#include <stack>
#include <map>
#include <set>
#include <queue>
#include <string>
#include <cstring>
#include <algorithm>
#include <iomanip> //fixed<<setprecision(12)<<
#include <utility> //pair模板
#include <cmath>
#include <random> //mt19937 mtrand(time(0));
#include <time.h>
#define close \
std::ios::sync_with_stdio(false); \
cin.tie(0); \
cout.tie(0)
typedef long long ll;
typedef unsigned long long ull;
const double pi = 3.141592653589793;
const int inf = 2e9;
const int N = 2e5 + 7;
const ll mod = 998244353;
using namespace std;
ll y, m, d, cnt;
string a[5] = {"Monday", "Tuesday", "Wednesday", "Thursday", "Friday"};
string s;
void solve()
{
// freopen("data.in.txt","r",stdin);
// freopen("data.out.txt","w",stdout);
cin >> y >> m >> d;
cnt = d;
cin >> s >> y >> m >> d;
cnt = d - cnt;
cnt %= 5;
cnt = (cnt + 5) % 5;
// cout << cnt << endl;
int pos = 0;
for (int i = 0; i < 5; i++)
if (a[i] == s)
{
pos = i;
break;
}
pos += cnt;
pos %= 5;
cout << a[pos] << endl;
}
signed main()
{
close;
int t = 1;
cin >> t;
while (t--)
{
solve();
}
return 0;
}
C. Wandering Robot
#include <iostream>
#include <vector>
#include <stack>
#include <map>
#include <set>
#include <queue>
#include <string>
#include <cstring>
#include <algorithm>
#include <iomanip> //fixed<<setprecision(12)<<
#include <utility> //pair模板
#include <cmath>
#include <random> //mt19937 mtrand(time(0));
#include <time.h>
#define close \
std::ios::sync_with_stdio(false); \
cin.tie(0); \
cout.tie(0)
typedef long long ll;
typedef unsigned long long ull;
const double pi = 3.141592653589793;
const int inf = 2e9;
const int N = 2e5 + 7;
const ll mod = 998244353;
using namespace std;
ll len, n;
string s;
void solve()
{
// freopen("data.in.txt","r",stdin);
// freopen("data.out.txt","w",stdout);
ll mx = 0;
ll x = 0, y = 0;
cin >> len >> n >> s;
for (int i = 0; i < len; i++)
{
if (s[i] == 'U')
y++;
else if (s[i] == 'D')
y--;
else if (s[i] == 'L')
x--;
else if (s[i] == 'R')
x++;
mx = max(mx, abs(x) + abs(y));
}
x *= (n - 1);
y *= (n - 1);
for (int i = 0; i < len; i++)
{
if (s[i] == 'U')
y++;
else if (s[i] == 'D')
y--;
else if (s[i] == 'L')
x--;
else if (s[i] == 'R')
x++;
mx = max(mx, abs(x) + abs(y));
}
cout << mx << endl;
}
signed main()
{
close;
int t = 1;
cin >> t;
while (t--)
{
solve();
}
return 0;
}
D. Game on a Graph
取的最多个数就是m-n+1 看看谁取下一个 另一个团队的人就赢了
#include <iostream>
#include <vector>
#include <stack>
#include <map>
#include <set>
#include <queue>
#include <string>
#include <cstring>
#include <algorithm>
#include <iomanip> //fixed<<setprecision(12)<<
#include <utility> //pair模板
#include <cmath>
#include <random> //mt19937 mtrand(time(0));
#include <time.h>
#define close \
std::ios::sync_with_stdio(false); \
cin.tie(0); \
cout.tie(0)
typedef long long ll;
typedef unsigned long long ull;
const double pi = 3.141592653589793;
const int inf = 2e9;
const int N = 2e5 + 7;
const ll mod = 998244353;
using namespace std;
void solve()
{
// freopen("data.in.txt","r",stdin);
// freopen("data.out.txt","w",stdout);
int k;
cin>>k;
string s;cin>>s;s=" "+s;
int n,m;cin>>n>>m;
for(int i=1;i<=m;i++){
int u,v;cin>>u>>v;
}
int tmp=m-n+1;
tmp++;
tmp=(tmp-1)%k+1;
if(s[tmp]=='1') cout<<"2\n";
else cout<<"1\n";
}
signed main()
{
close;
int t = 1;
cin>>t;
while (t--)
{
solve();
}
return 0;
}
F. Stones in the Bucket
让所有数字一样 至少需要几步
贪心 最少步数的时候肯定是每个数在到达可能最大的平均值
#include <iostream>
#include <vector>
#include <stack>
#include <map>
#include <set>
#include <queue>
#include <string>
#include <cstring>
#include <algorithm>
#include <iomanip> //fixed<<setprecision(12)<<
#include <utility> //pair模板
#include <cmath>
#include <random> //mt19937 mtrand(time(0));
#include <time.h>
#define close \
std::ios::sync_with_stdio(false); \
cin.tie(0); \
cout.tie(0)
typedef long long ll;
typedef unsigned long long ull;
#define int ll
const double pi = 3.141592653589793;
const int inf = 2e9;
const int N = 2e5 + 7;
const ll mod = 998244353;
using namespace std;
int a[N];
void solve()
{
// freopen("data.in.txt","r",stdin);
// freopen("data.out.txt","w",stdout);
int n;cin>>n;
int sum=0;
for(int i=1;i<=n;i++){
cin>>a[i];
sum+=a[i];
}
int ans=0;
sum/=n;
for(int i=1;i<=n;i++){
if(a[i]>sum){
ans+=a[i]-sum;
}
}
cout<<ans<<'\n';
}
signed main()
{
close;
int t = 1;
cin>>t;
while (t--)
{
solve();
}
return 0;
}
L. Median
给定数大小关系 看某个数是否可能变成中位数
用弗洛伊德算法求传递凸包,如果一个数到达它的数不超过n/2 它到达的也不超过n/2就可以
如果某个数既能到达它 它又能到达 那就是不可能的
(无视这个tarjan
#include <iostream>
#include <vector>
#include <stack>
#include <map>
#include <set>
#include <queue>
#include <string>
#include <cstring>
#include <algorithm>
#include <iomanip> //fixed<<setprecision(12)<<
#include <utility> //pair模板
#include <cmath>
#include <random> //mt19937 mtrand(time(0));
#include <time.h>
#define close \
std::ios::sync_with_stdio(false); \
cin.tie(0); \
cout.tie(0)
typedef long long ll;
typedef unsigned long long ull;
const double pi = 3.141592653589793;
const int inf = 0x3f3f3f3f;
const int N = 2e5 + 7;
const ll mod = 998244353;
using namespace std;
int ans[N];
int d[105][105];
int cnt;
int low[N], num[N], dfn;
int sccno[N], sta[N], top;
vector<int> G[N];
void dfs(int u)
{
sta[top++] = u;
low[u] = num[u] = ++dfn;
for (int i = 0; i < G[u].size(); i++)
{
int v = G[u][i];
if (!num[v])
{
dfs(v);
low[u] = min(low[v], low[u]);
}
else if (!sccno[v])
{
low[u] = min(low[u], num[v]);
}
}
if (low[u] == num[u])
{
cnt++;
while (1)
{
int v = sta[--top];
sccno[v] = cnt;
if (u == v)
break;
}
}
}
void Tarjan(int n)
{
cnt = top = dfn = 0;
memset(sccno, 0, sizeof sccno);
memset(num, 0, sizeof num);
memset(low, 0, sizeof low);
for (int i = 1; i <= n; i++)
{
if (!num[i])
{
dfs(i);
}
}
}
void solve()
{
int n, m, vaild = 1;
cin >> n >> m;
memset(d, 0x3f3f3f3f, sizeof(d));
for (int i = 0; i <= n; i++)
{
G[i].clear();
}
for (int i = 1; i <= m; i++)
{
int x, y;
cin >> x >> y;
if (x == y)
vaild = 0;
G[y].push_back(x); // taj
d[x][y] = 1;
}
Tarjan(n);
if (cnt != n)
vaild = 0;
if (vaild == 0)
{
for (int i = 1; i <= n; i++)
{
cout << '0';
}
cout << '\n';
return;
}
for (int k = 1; k <= n; k++)
{
for (int u = 1; u <= n; u++)
{
for (int v = 1; v <= n; v++)
{
d[u][v] = min(d[u][v], d[u][k] + d[k][v]);
}
}
}
for (int i = 1; i <= n; i++)
{
int In = 0, Out = 0;
for (int j = 1; j <= n; j++)
{
if (i == j)
continue;
if (d[i][j] != inf && d[j][i] != inf)
vaild = 0;
if (d[i][j] != inf)
In++;
if (d[j][i] != inf)
Out++;
if (In <= (n / 2) && Out <= (n / 2))
ans[i] = 1;
else
ans[i] = 0;
}
}
if (vaild == 0)
{
for (int i = 1; i <= n; i++)
{
cout << '0';
}
cout << '\n';
return;
}
for (int i = 1; i <= n; i++)
cout << ans[i];
cout << "\n";
// freopen("data.in.txt","r",stdin);
// freopen("data.out.txt","w",stdout);
}
signed main()
{
close;
int t = 1;
cin >> t;
while (t--)
{
solve();
}
return 0;
}
M. Sekiro
钱的数量超出就直接输出1 其他的暴力跑 复杂度不高
#include <iostream>
#include <vector>
#include <stack>
#include <map>
#include <set>
#include <queue>
#include <string>
#include <cstring>
#include <algorithm>
#include <iomanip> //fixed<<setprecision(12)<<
#include <utility> //pair模板
#include <cmath>
#include <random> //mt19937 mtrand(time(0));
#include <time.h>
#define close \
std::ios::sync_with_stdio(false); \
cin.tie(0); \
cout.tie(0)
typedef long long ll;
typedef unsigned long long ull;
#define int long long
const double pi = 3.141592653589793;
const int inf = 2e9;
const int N = 2e5 + 7;
const ll mod = 998244353;
using namespace std;
int fac[40];
void init()
{
fac[0] = 1;
for (int i = 1; i <= 30; i++)
{
fac[i] = fac[i - 1] * 2;
}
}
void solve()
{
int n;
int k;
cin >> n >> k;
if (n == 0)
{
cout << 0 << "\n";
return;
}
if (k >= 31)
{
cout << 1 << '\n';
return;
}
for (int i = 1; i <= k; i++)
{
if (n % 2)
n = n / 2 + 1;
else
n /= 2;
}
cout << n << '\n';
// freopen("data.in.txt","r",stdin);
// freopen("data.out.txt","w",stdout);
}
signed main()
{
close;
init();
int t = 1;
cin >> t;
while (t--)
{
solve();
}
return 0;
}
E. BaoBao Loves Reading
和之前那个好像 但是不能那样想
这次要考虑某一个数有贡献的条件是容量大于中间不同数的数量
那么我们就算出每一个数什么时候有贡献就行了
经典树状数组扫描线求数种类
#include<bits/stdc++.h>
#define close std::ios::sync_with_stdio(false),cin.tie(0),cout.tie(0)
using namespace std;
typedef long long ll;
const ll MAXN = 3e5+7;
const ll mod = 1e9+7;
const ll inf = 0x3f3f3f3f;
int last[MAXN],ans[MAXN];
struct BIT {
int t[MAXN]={0};
BIT(){
memset(t,0,sizeof(t));
}
int lowbit(int x) {
return x&-x;
}
ll getsum(int x) {
ll sum=0;
while(x) {
sum+=t[x];
x-=lowbit(x);
}
return sum;
}
void addv(int x,int val) {
while(x<=MAXN) {
t[x]+=val;
x+=lowbit(x);
}
}
};
void solve(){
BIT T;
int n;cin>>n;
for(int i=1;i<=n;i++) last[i]=0,ans[i]=0;
for(int i=1;i<=n;i++){
int x;cin>>x;
if(last[x]==0){
T.addv(i,1);
}
else{
T.addv(last[x],-1);
T.addv(i,1);
int sum=T.getsum(i)-T.getsum(last[x]-1);
ans[sum]++;
}
last[x]=i;
}
for(int i=1;i<=n;i++) ans[i]=ans[i-1]+ans[i];
for(int i=1;i<=n;i++) {
cout<<n-ans[i];
if(i!=n) cout<<" ";
}
cout<<'\n';
}
signed main(){
close;
int t;cin>>t;
while(t--)
solve();
}
H. Tokens on the Segments
每个线段放一个石头就会贡献+1,但是不能在一个位置放两个石头,问最多贡献
用set模拟也可以做
用优先队列方便 先取最左边的 可以取就丢掉 不能取就把它的头-1
#include<bits/stdc++.h>
#define close std::ios::sync_with_stdio(false),cin.tie(0),cout.tie(0)
using namespace std;
typedef long long ll;
const ll MAXN = 3e5+7;
const ll mod = 1e9+7;
const ll inf = 0x3f3f3f3f;
#define int ll
priority_queue<pair<int,int> > que;
void solve(){
int n;cin>>n;
while(que.size()) que.pop();
for(int i=1;i<=n;i++){
int l,r;cin>>l>>r;
que.push({l*-1,r*-1});
}
int ans=0,now=0;
while(que.size()){
auto st=que.top();
que.pop();
if(st.first*-1>now){
now=st.first*-1;
ans++;
}
else {
int x=st.first;
x*=-1;
x++;
int y=st.second;
y*=-1;
if(x>y);
else que.push({x*-1,y*-1});
}
}
cout<<ans<<'\n';
}
signed main(){
close;
int t;cin>>t;
while(t--)
solve();
}
I. Connected Intervals
要统计出符合条件的区间的数量,意思是(L,R)是从L-R的所有点
只看这些点的时候 如果连通块数量是1 就符合条件
考虑扫描线 在加入一个数 3 的时候 假设3是一个完全独立的点 不与其他数相连 所有区间 如(1,3),(2,3),(3,3)的连通块数量都会+1
但是如果告诉你 3和2连接 那3加入(2,3)的时候 其实连通块数量没有+1 那就给2,3的数量-1 然后1,3的同理也要-1
设线段树上的点 1 2 3 4 ...... 表示区间的左端点 扫到3 就表示到3位为止的区间,然后up的时候统计线段内最小值和最小值的数量
如果最小值==1 就return cnt,意思就是让线段树来找为1 的点的个数
#include<bits/stdc++.h>
#define close std::ios::sync_with_stdio(false),cin.tie(0),cout.tie(0)
using namespace std;
#define int ll
typedef long long ll;
const ll MAXN = 3e5+7;
const ll mod = 1e9+7;
const ll inf = 0x3f3f3f3f;
vector<int> adj[MAXN];
struct Info {
int mn,cnt;
};
Info operator +(const Info &a,const Info &b) {
Info c;
c.mn=min(a.mn,b.mn);
c.cnt=0;
if(c.mn==a.mn) c.cnt+=a.cnt;
if(c.mn==b.mn) c.cnt+=b.cnt;
return c;
}
struct node {
int lazy;
Info val;
} seg[MAXN<<2];
void up(int id) {
seg[id].val=seg[id<<1].val+seg[id<<1|1].val;
}
void settag(int id,int l,int r,int tag) {
seg[id].val.mn+=tag;
seg[id].lazy+=tag;
}
void down(int id,int l,int r) {
if(seg[id].lazy==0) return;
int mid=l+r>>1;
settag(id<<1,l,mid,seg[id].lazy);
settag(id<<1|1,mid+1,r,seg[id].lazy);
seg[id].lazy=0;
}
void build(int id,int l,int r) {
seg[id].lazy=0;
seg[id].val.cnt=0;
if(l==r) {
seg[id].val.mn=0;
seg[id].val.cnt=1;
return;
}
int mid = l+r>>1;
build(id<<1,l,mid);
build(id<<1|1,mid+1,r);
up(id);
}
void modify(int id,int l,int r,int ql,int qr,int val) {
if (ql==l&&r==qr) {
settag(id,l,r,val);
return;
}
down(id,l,r);
int mid =(l+r) >> 1;
if (qr<=mid)
modify(id <<1,l,mid,ql,qr,val);
else if (ql>mid)
modify(id<<1|1, mid+1,r,ql,qr,val);
else {
modify(id<<1,l,mid,ql,mid,val);
modify(id<<1|1,mid+1,r,mid+1,qr,val);
}
up(id);
}
int query(int id,int l ,int r,int ql,int qr) {
if(ql==l&&r==qr) {
if(seg[id].val.mn==1)
return seg[id].val.cnt;
else return 0;
}
down(id,l,r);
int mid=l+r>>1;
if(qr<=mid) return query(id<<1,l,mid,ql,qr);
else if(ql>mid) return query(id<<1|1,mid+1,r,ql,qr);
else return query(id<<1,l,mid,ql,mid)+query(id<<1|1,mid+1,r,mid+1,qr);
}
void solve() {
int n;cin>>n;
build(1,1,n);
for(int i=1;i<=n;i++){
adj[i].clear();
}
for(int i=1;i<n;i++){
int u,v;cin>>u>>v;
adj[u].push_back(v);
adj[v].push_back(u);
}
int ans=0;
for(int i=1;i<=n;i++){
modify(1,1,n,1,i,1);
for(auto &v:adj[i]){
if(v<i){
modify(1,1,n,1,v,-1);
}
}
ans+=query(1,1,n,1,i);
}
cout<<ans<<"\n";
}
signed main() {
close;
int t;cin>>t;
while(t--)
solve();
}
K. Happy Equation
打了个表 发现a为奇数始终输出1
在x>p的时候 我们可以发现 因为a里面至少有一个2的因子,
2的x次方乘上一堆数必定能被2的p次方整除 所以在x>p时 我们求x的a次方%2的p次方为0的数就行了
在x<=p的时候 枚举这个x 统计答案
在x>p的时候 我们需要让x里面2的因数的数量cnt *a>=p 这样就能整除了
然后我们可以算出cnt最少需要多少个
假如说cnt至少需要2个 x是属于(p,2^p)的 就相当于算 p-2^p之间有多少2的2次方(4)的倍数
除一下再减一下就好了
#include<bits/stdc++.h>
#define close std::ios::sync_with_stdio(false),cin.tie(0),cout.tie(0)
using namespace std;
typedef long long ll;
const ll MAXN = 3e5+7;
ll mod;
const ll inf = 0x3f3f3f3f;
#define int ll
ll _power(ll a,int b) {
ll ans=1,res=a;
while(b) {
if(b&1)
ans=ans*res%mod;
res=res*res%mod;
b>>=1;
}
return ans%mod;
}
void solve() {
int a,p;
cin>>a>>p;
if(a%2==1) {
cout<<1<<"\n";
return;
}
mod=(1<<p);
int ans=0;
for(int x=2; x<=p; x+=2) { //统计x<=p的时候 合法的数量
if(_power(a,x)==_power(x,a)) ans++;
}
int k=p/a;
if(k*a!=p) k++;
ans+=pow(2,p-k);
int l=p/pow(2,k);
ans-=l;
printf("%lld\n",ans);
//cout<<ans-p/(pow(2,k))<<"\n";//此时必须满足x> p
}
signed main() {
int t;
cin>>t;
while(t--)
solve();
}
2023暑期训练后半
1. 2023 Xian Jiaotong University Programming Contest
赛时过题ABCDEFHMN 补题GJO
2. 2019-2020 ACM-ICPC Brazil Subregional Programming Contest
3. 2019 ICPC Universidad Nacional de Colombia Programming
赛时过题BGIK 补CDJ
B. Boring Non-Palindrome
签到 队友写的
void solve()
{
// freopen("data.in.txt","r",stdin);
// freopen("data.out.txt","w",stdout);
cin >> s;
int n = s.length();
s = ' ' + s;
for (int i = 1; i <= n; i++)
{
int l = i, r = n;
while (l <= r)
{
if (s[l] == s[r])
{
l++, r--;
}
else
{
break;
}
}
if (r < l)
{
cout << s;
for (int j = i - 1; j > 0; j--)
cout << s[j];
return;
}
}
}
C. Common Subsequence
类似求最长匹配的dp 队友补了
D. Do Not Try This Problem
并查集+根号分治
间隔长的直接跳就行了 短的用并查集暴力维护下一个跳的
int f[MAXN][320];//用并查集跳边
int vis[MAXN];
struct node{
int s,d,p;
char ch;
}N[MAXN];
void clean(int n){
for(int j=1;j<=n;j++)
for(int i=1;i<320;i++){
f[j][i]=j;
}
}
int find(int x,int k){
if(x!=f[x][k]) f[x][k]=find(f[x][k],k);
return f[x][k];
}
void add(int x,int y,int k){
int fx=find(x,k),fy=find(y,k);
if(fx!=fy) f[fx][k]=fy;
}
void solve(){
string str;cin>>str;
int n=str.length();
str=" "+str;
int k=sqrt(n);
clean(n);
int q;cin>>q;
for(int i=1;i<=q;i++){
int s,d,p;cin>>N[i].s>>N[i].d>>N[i].p;
char ch;cin>>N[i].ch;
}
for(int i=q;i>=1;i--){
int s=N[i].s,d=N[i].d,p=N[i].p;
char ch=N[i].ch;
if(d>k){
for(int j=s;j<=min(s+p*d,n);j+=d){
if(!vis[j]){
vis[j]=1;
str[j]=ch;
}
}
}
else{
int now=s;
while(now<=min(s+p*d,n)){
now=find(now,d);
if(now>min(s+p*d,n)) break;
if(!vis[now]){
vis[now]=1;
str[now]=ch;
if(now+d<=n)
add(now,now+d,d);
now+=d;
}
else{
if(now+d<=n)
add(now,now+d,d);
now+=d;
}
}
}
// cout<<i<<str<<"\n";
}
for(int i=1;i<=n;i++) cout<<str[i];
}
E. Extreme Image
圆形的扫描线 还没补
F. Fraction Formula
模拟
G. Graduation
struct E
{
int to, w, next;
} edge[M];
int head[N], tot;
int sz[N];
int n, k;
void add(int u, int v, int w)
{
tot++;
edge[tot].to = v;
edge[tot].w = w;
edge[tot].next = head[u];
head[u] = tot;
}
void dfs(int u, int f)
{
sz[u] = 1;
for (int i = head[u]; i; i = edge[i].next)
{
int v = edge[i].to, w = edge[i].w;
dfs(v, u);
sz[u] += sz[v];
}
}
struct cmp
{
bool operator()(int &a, int &b)
{
return sz[a] < sz[b];
}
};
void solve()
{
cin >> n >> k;
vector<int> s;
for (int i = 1, f; i <= n; i++)
{
cin >> f;
if (f == 0)
s.push_back(i);
add(f, i, 0);
}
for (auto i : s)
dfs(i, 0);
priority_queue<int, vector<int>, cmp> q;
for (auto i : s)
q.push(i);
int ans = 0;
while (q.size())
{
vector<int> tp;
for (int i = 1; q.size() && i <= k; i++)
{
int u = q.top();
q.pop();
for (int i = head[u]; i; i = edge[i].next)
{
tp.push_back(edge[i].to);
}
}
for (auto i : tp)
q.push(i);
ans++;
}
cout << ans;
}
I. Integer Prefix
签到
void solve()
{
string s;
cin >> s;
vector<char> ans;
for (auto x : s)
{
if (x <= '9' && x >= '0')
ans.push_back(x);
else
break;
}
if (ans.size() == 0)
cout << -1 << '\n';
else
for (auto x : ans)
{
cout << x;
}
}
J. Jail Destruction
砍墙 势能线段树 但是我势能用错了t了
要算非0的最小值 这样最后是可以执行区间加的 保持势能
#define int ll
int a[MAXN];
struct Info{
int mn,sum,len;
};
Info operator +(const Info &a,const Info &b){
Info c;
c.len=a.len+b.len;
c.mn=min(a.mn,b.mn);
c.sum=a.sum+b.sum;
return c;
}
struct node{
int lazy;
Info val;
}seg[MAXN<<2];
void settag(int id,int l,int r,int val){
seg[id].val.mn+=val;
seg[id].val.sum+=(seg[id].val.len)*val;
seg[id].lazy+=val;
}
void up(int id){
seg[id].val=seg[id<<1].val+seg[id<<1|1].val;
}
void down(int id,int l,int r){
if(seg[id].lazy==0) return ;
int mid=l+r>>1;
settag(id<<1,l,mid,seg[id].lazy);
settag(id<<1|1,mid+1,r,seg[id].lazy);
seg[id].lazy=0;
}
void build(int id,int l,int r){
if(l==r){
seg[id].val.mn=a[l];
seg[id].val.len=1;
seg[id].val.sum=a[l];
seg[id].lazy=0;
return;
}
int mid=l+r>>1;
build(id<<1,l,mid);
build(id<<1|1,mid+1,r);
up(id);
}
void modify(int id,int l,int r,int ql,int qr,int val){
if(ql==l&&qr==r&&seg[id].val.mn+val>=0){
settag(id,l,r,val);
return;
}
if(seg[id].val.len==0) return;
if(l==r){
seg[id].val.sum=0;
seg[id].val.mn=inf;
seg[id].val.len=0;
return;
}
down(id,l,r);
int mid=l+r>>1;
if(qr<=mid) modify(id<<1,l,mid,ql,qr,val);
else if(ql>mid) modify(id<<1|1,mid+1,r,ql,qr,val);
else{
modify(id<<1,l,mid,ql,mid,val);
modify(id<<1|1,mid+1,r,mid+1,qr,val);
}
up(id);
}
Info query(int id,int l,int r,int ql,int qr){
if(ql==l&&r==qr){
return seg[id].val;
}
down(id,l,r);
int mid=l+r>>1;
if(qr<=mid) return query(id<<1,l,mid,ql,qr);
else if(ql>mid) return query(id<<1|1,mid+1,r,ql,qr);
else{
return query(id<<1,l,mid,ql,mid)+query(id<<1|1,mid+1,r,mid+1,qr);
}
}
void solve()
{
int n,m;cin>>n>>m;
for(int i=1;i<=n;i++) cin>>a[i];
build(1,1,n);
for(int i=1;i<=m;i++){
int op;cin>>op;
if(op==1){
int l,r;cin>>l>>r;
if(r>=l) cout<<query(1,1,n,l,r).sum<<"\n";
else{
cout<<query(1,1,n,1,r).sum+query(1,1,n,l,n).sum<<"\n";
}
}
else{
int l,r,w;cin>>l>>r>>w;
if(r>=l) modify(1,1,n,l,r,-w);
else{
modify(1,1,n,1,r,-w);
modify(1,1,n,l,n,-w);
}
}
}
}
K. Kernel Of Love
签到
void solve()
{
int n;
cin >> n;
if (n == 1)
cout << 0 << '\n';
else if (n == 2)
cout << 0 << '\n';
else if (n == 3)
cout << 2 << '\n';
else if (n == 4)
cout << 3 << '\n';
else
cout << (n - 4) / 3 * 2 + 3 + ((n - 4) % 3 >= 2) << '\n';
}
4. 2018-2019 9th BSUIR Open Programming Championship
赛时过题AEFH 补题IK
A. Four minutes until BSUIR Open
int n;
double a1, a2, x[N], v[N];
double count(double v0, double v1, double x)
{
double a = (a1 * a1 + a1 * a2);
double b = 2.0 * v0 * (a1 + a2);
double c = v0 * v0 - v1 * v1 - 2.0 * a2 * x;
// cout << a << ' ' << b << ' ' << c << endl;
double t = (-b + sqrt(b * b - 4.0 * a * c)) / (2.0 * a);
// cout << t + (v0 - v1 + a1 * t) / a2 << endl;
return t + (v0 - v1 + a1 * t) / a2;
}
void solve()
{
// freopen("data.in.txt","r",stdin);
// freopen("data.out.txt","w",stdout);
// cout << sqrt(6) << endl;
cin >> n >> a1 >> a2;
for (int i = 1; i <= n; i++)
cin >> x[i] >> v[i];
for (int i = n; i > 0; i--)
{
v[i - 1] = min(v[i - 1], sqrt(2.0 * a2 * (x[i] - x[i - 1]) + v[i] * v[i]));
}
for (int i = 0; i < n; i++)
{
v[i + 1] = min(v[i + 1], sqrt(2.0 * a1 * (x[i + 1] - x[i]) + v[i] * v[i]));
}
double ans = 0;
for (int i = 1; i <= n; i++)
{
ans += count(v[i - 1], v[i], x[i] - x[i - 1]);
}
cout << fixed << setprecision(7) << ans << endl;
}
E. Small business
*Edgrass 搓了好久的模拟 类目了 居然给他过了
裱起来(
#include<bits/stdc++.h>
#define ll long long
#define PII pair<int,int>
// #define int long long
using namespace std;
const ll mod=1e9+7;
const ll inf=0x3f3f3f3f;
const ll INF=0x3f3f3f3f3f3f3f3f;
const double eps=1e-10;
const int N=2e5+10;
// struct node{
// friend bool operator<(const node&a,const node&b){
// return ;
// }
// }
inline int read(){int x=0,f=1;char ch=getchar();while(ch<'0'||ch>'9'){if(ch=='-')f=-1;ch=getchar();}while(ch>='0'&&ch<='9'){x=(x<<1)+(x<<3)+(ch^48);ch=getchar();}return x*f;}
inline void write(int x){char F[200];int tmp=x>0?x:-x;if(x<0) putchar('-');int cnt=0;while(tmp>0){F[cnt++]=tmp%10+'0';tmp/=10;}while(cnt>0)putchar(F[--cnt]);}
inline int combination(int n,int k){int sum=0;if (n==k||k==0){return 1;}else{return combination(n-1,k)+combination(n-1,k-1);}}
void solve(){
string s;
cin>>s;
int n=s.size(),cnt0=0;
vector<int>vec;
for(auto x:s){
if(x=='0')cnt0++;
else vec.push_back(x-'0');
}
for(int i=1;i<=n;i++){
if(i>n-i||(n-i)>19||i>19)continue;
priority_queue<int,vector<int>,greater<int> >pq;
for(auto x:vec){
pq.push(x);
}
int cnt=cnt0,ok=1;
vector<int>ans1,ans2;
if(n-i==19){
for(int i=1;i<=18;i++){
cnt--;
}
if(pq.size()==0){
ok=0;
continue;
}
int t=pq.top();
pq.pop();
if(cnt<0||t!=1)continue;
else {
if(i==1){
if(cnt){
cnt--;
ans1.push_back(0);
}
}
if(ans1.size()!=i){
if(ok==0||pq.size()==0){
continue;
}
ans1.push_back(pq.top());
pq.pop();
for(int j=2;j<=i&&ok;j++){
if(cnt)ans1.push_back(0),cnt--;
else if(pq.size()==0){
ok=0;
break;
}else ans1.push_back(pq.top()),pq.pop();
}
}
if((ans1[0]!=1||ans1[ans1.size()-1]!=0)&&ans1.size()==19)continue;
for(auto x:ans1){
cout<<x;
}
cout<<" 1000000000000000000\n";
}
return ;
}
if(i==1){
if(cnt){
cnt--;
ans1.push_back(0);
}
}
if(n-i==1){
if(cnt){
cnt--;
ans2.push_back(0);
}
}
if(ans1.size()!=i){
if(ok==0||pq.size()==0){
continue;
}
ans1.push_back(pq.top());
pq.pop();
for(int j=2;j<=i&&ok;j++){
if(cnt)ans1.push_back(0),cnt--;
else if(pq.size()==0){
ok=0;
break;
}else ans1.push_back(pq.top()),pq.pop();
}
}
if(ans2.size()!=n-i){
if(ok==0||pq.size()==0){
continue;
}
ans2.push_back(pq.top());
pq.pop();
for(int j=2;j<=(n-i);j++){
if(cnt)ans2.push_back(0),cnt--;
else if(pq.size()==0){
ok=0;
break;
}else ans2.push_back(pq.top()),pq.pop();
}
if(ok==0||pq.size()!=0||cnt!=0){
continue;
}
}
if((ans2[0]!=1||ans2[ans2.size()-1]!=0)&&ans2.size()==19)continue;
if((ans1[0]!=1||ans1[ans1.size()-1]!=0)&&ans1.size()==19)continue;
for(auto x:ans1){
cout<<x;
}
cout<<" ";
for(auto x:ans2){
cout<<x;
}
cout<<'\n';
return ;
}
cout<<-1<<" "<<-1<<'\n';
//puts(ans>0?"YES":"NO");
//puts(ans>0?"Yes":"No");
}
F. Prime or number
void solve()
{
int n;
cin >> n;
if (n == 1)
{
cout << "No\n";
return;
}
int x = n, cnt = 0;
while (x)
{
if (x % 2)
cnt++;
x /= 2;
}
if (cnt == 1)
cout << "Yes\n";
else if (cnt == 2 && n % 2)
cout << "Yes\n";
else
cout << "No\n";
// freopen("data.in.txt","r",stdin);
// freopen("data.out.txt","w",stdout);
}
H. Nonfibonacci numbers
有几个数字固定不会出现 数位dp
int f[N][N][2][2], num[N], now;
int dfs(int pos, int sum, bool lead, bool limit)
{
int ans = 0;
if (pos == 0)
return 1;
if (f[pos][sum][limit][lead] != -1)
return f[pos][sum][limit][lead];
int up = (limit ? num[pos] : 9);
// cout<<"pos:"<<pos<<" "<<up<<'\n';
for (int i = 0; i <= up; i++)
{
if (i == 1 || i == 2 || i == 3 || i == 5 || i == 8)
continue;
if (i == 0 && lead)
ans += dfs(pos - 1, sum, true, limit &&i == up);
else
ans += dfs(pos - 1, sum + 1, false, limit &&i == up);
}
f[pos][sum][limit][lead] = ans;
return ans;
}
void solve()
{
int n=read();
int x = n, len = 0;
while (x)
{
num[++len] = x % 10;
x /= 10;
}
memset(f, -1, sizeof f);
cout << dfs(len, 0, true, true) << '\n';
// freopen("data.in.txt","r",stdin);
// freopen("data.out.txt","w",stdout);
}
I. Equal Mod Segments
求连续mod 从左到右和从右到左一样的区间个数
用二分求对每个数来说 向下取的区间
线段树补充 - xishuiw - 博客园 (cnblogs.com)
丢这了 扫描线
K. Innovations
垃圾做法 树剖 但是赛场上线段树板子抄错了
ll a[MAXN];
vector<pair<int,ll> > adj[MAXN];
int deep[MAXN],siz[MAXN],hson[MAXN],rak[MAXN],dfn[MAXN],f[MAXN],cnt=0,top[MAXN];
ll ans=0,sum;
void tree_build(int u,int fa,int dep) {
deep[u]=dep;
siz[u]=1;
f[u]=fa;
for(auto &it:adj[u]) {
int v=it.first;
if(v==fa) continue;
ll w=it.second;
a[v]=w;
tree_build(v,u,dep+1);
siz[u]+=siz[v];
if(hson[u]==0||siz[v]>siz[hson[u]]) hson[u]=v;
}
}
void tree_decom(int u,int t) {
top[u]=t;
cnt++;
dfn[u]=cnt;
rak[cnt]=u;
if(hson[u]!=0) {
tree_decom(hson[u],t);
for(auto &it:adj[u]) {
int v=it.first;
if(hson[u]!=v&&v!=f[u]) tree_decom(v,v);
}
}
}
struct Info {
ll sum;
bool flag;
};
Info operator +(const Info &a,const Info &b) {
Info c;
c.flag=(a.flag&b.flag);
return c;
}
struct node {
Info val;
} seg[MAXN<<2];
void up(int id) {
seg[id].val=seg[id<<1].val+seg[id<<1|1].val;
}
void build(int id,int l,int r) {
if(l==r) {
seg[id].val.sum=a[rak[l]];
if(a[rak[l]]==1) seg[id].val.flag=1;
return;
}
int mid=l+r>>1;
build(id<<1,l,mid);
build(id<<1|1,mid+1,r);
up(id);
}
void modify(int id,int l,int r,int ql,int qr,int val) {
if(seg[id].val.flag==1) return;
if(ql==l&&r==qr) {
if(seg[id].val.flag==1) {
return;
}
}
if(l==r) {
ll tmp=sqrt(seg[id].val.sum);
ll temp=seg[id].val.sum-tmp;
int sizz=siz[rak[l]];
ans-=(temp)*(sizz)*(sum-sizz);
ans%=mod;
if(ans<0) ans+=mod;
seg[id].val.sum=tmp;
if(tmp==1) seg[id].val.flag=1;
return;
}
int mid=(l+r)>>1;
if(qr<=mid) modify(id<<1,l,mid,ql,qr,val);
else if(ql>mid) modify(id<<1|1,mid+1,r,ql,qr,val);
else {
if(seg[id<<1].val.flag!=1)
modify(id<<1,l,mid,ql,mid,val);
if(seg[id<<1|1].val.flag!=1)
modify(id<<1|1,mid+1,r,mid+1,qr,val);
}
up(id);
}
void dfs(int u,int fa) {
for(auto &it:adj[u]) {
int v=it.first;
if(v==fa) continue;
ans+=a[v]*(siz[v])*(sum-siz[v]);
if(ans>mod)
ans%=mod;
dfs(v,u);
}
}
void solve() {
int n,q;
scanf("%d %d",&n,&q);
sum=n;
for(int i=1; i<n; i++) {
int u,v;
ll w;
scanf("%d %d %lld",&u,&v,&w);
adj[u].push_back({v,w});
adj[v].push_back({u,w});
}
tree_build(1,0,0);
tree_decom(1,1);
dfs(1,0);
build(1,1,n);
printf("%lld\n",ans);
for(int i=1; i<=q; i++) {
int u,v;
scanf("%d %d",&u,&v);
if(u==v||seg[1].val.flag==1) {
printf("%lld\n",ans);
continue;
}
while(top[u]!=top[v]) {
if(deep[top[u]]>deep[top[v]]) {
modify(1,1,n,dfn[top[u]],dfn[u],1);
u=f[top[u]];
} else {
modify(1,1,n,dfn[top[v]],dfn[v],1);
v=f[top[v]];
}
}
if(dfn[v]!=dfn[u]) {
if(dfn[v]<dfn[u]) swap(u,v);
modify(1,1,n,dfn[u]+1,dfn[v],1);
}
printf("%lld\n",ans);
}
}
5. 2019-2020 Winter Petrozavodsk Camp, Day 8: Almost Algorithmic Contest
只写了FG的超难场
6. 2020-2021 ACM-ICPC Brazil Subregional Programming Contest
赛时过题:ABFGL 补题:EHN(I)
A. Sticker Album
概率dp 一直想不明白怎么搞的样例 然后发现从0开始推
用前缀和(滑动窗口)优化速度
对于a==0的样例xlen/(len-) 就行了
半蒙的
void solve() {
int n,a,b;
cin>>n>>a>>b;
for(int i=1; i<=n; i++) {
int l=i-b;
int r=i-a;
if(i<=a) dp[i]=1;
else {
if(l>0){
if(a!=0)
dp[i]=(pre[r]-pre[l-1]+r-l+1)/(b-a+1);
else{
dp[i]=(pre[r-1]-pre[l-1]+(r-l+1))/(b-a+1);
dp[i]*=(b-a+1)*1.0/(b-a);
}
}
else{
if(a!=0)
dp[i]=(pre[r]+r-l+1)/(b-a+1);
else{
dp[i]=(pre[r-1]+r-l+1)/(b-a+1);
dp[i]*=(b-a+1)*1.0/(b-a);
}
}
}
pre[i]=pre[i-1]+dp[i];
// cout<<"i "<<i<<" :"<<dp[i]<<"\n";
}
printf("%.8f",dp[n]);
}
B. Battleship
队友签到的
int mp[20][20], n;
void solve()
{
// freopen("data.in.txt","r",stdin);
// freopen("data.out.txt","w",stdout);
cin >> n;
for (int i = 1; i <= n; i++)
{
int d, l, r, c;
cin >> d >> l >> r >> c;
for (int i = 0; i < l; i++)
{
int x = r, y = c;
if (d == 0)
y += i;
else
x += i;
if (x > 10 || y > 10 || mp[x][y] == 1)
{
cout << "N";
return;
}
mp[x][y] = 1;
}
}
cout << "Y";
}
E. Party Company
扫描线 赛场没写出来
树状数组维护符合的下界数量
int t[MAXN];
int lowbit(int x) {
return x&-x;
}
ll getsum(int x) {
ll sum=0;
while(x) {
sum+=t[x];
x-=lowbit(x);
}
return sum;
}
void addv(int x,int val) {
while(x<=MAXN) {
t[x]+=val;
x+=lowbit(x);
}
}
struct E {
int to,w,next;
} edge[M];
int head[N],tot;
void add(int u,int v,int w) {
tot++;
edge[tot].to=v;
edge[tot].w=w;
edge[tot].next=head[u];
head[u]=tot;
}
int fa[N][20];
int w[MAXN];
vector<int> node[MAXN];
int ans[MAXN],far[MAXN];
void dfs(int u,int f) {
fa[u][0]=f;
for(int i=1; i<20; i++)fa[u][i]=fa[fa[u][i-1]][i-1];
for(int i=head[u]; i; i=edge[i].next) {
int v=edge[i].to,w=edge[i].w;
if(v==f)continue;
dfs(v,u);
}
}
int gettop(int u,int mx) {
for(int i=19; i>=0; i--) {
if(w[fa[u][i]]<=mx)u=fa[u][i];
}
return u;
}
void calc(int u,int fa) {
for(auto &it:node[u]) {
addv(it,1);
}
ans[u]=getsum(w[u]);
for(int i=head[u]; i; i=edge[i].next) {
int v=edge[i].to;
if(v==fa) continue;
calc(v,u);
}
for(auto &it:node[u]) {
addv(it,-1);
}
}
void solve() {
int n,m;
cin>>n>>m;
for(int i=1; i<=n; i++) {
int u;
cin>>w[i]>>u;
if(i!=1)
add(i,u,1);
add(u,i,1);
far[i]=u;
}
far[1]=0;
dfs(1,1);
for(int i=1; i<=m; i++) {
int u,l,r;
cin>>u>>l>>r;
int top=gettop(u,r);
node[top].push_back(l);
}
calc(1,1);
for(int i=1; i<=n; i++) cout<<ans[i]<<" ";
}
F. Fastminton
模拟
string s;
void solve()
{
// freopen("data.in.txt","r",stdin);
// freopen("data.out.txt","w",stdout);
int ls = 0, rs = 0, lcnt = 0, rcnt = 0, tag = 0;
cin >> s;
// bool flag=true;
for (int i = 0; i < s.length(); i++)
{
if (s[i] == 'Q')
{
if (ls == 2)
printf("2 (winner) - %d\n", rs);
else if (rs == 2)
printf("%d - 2 (winner)\n", ls);
else if (tag == 0)
printf("%d (%d*) - %d (%d)\n", ls, lcnt, rs, rcnt);
else
printf("%d (%d) - %d (%d*)\n", ls, lcnt, rs, rcnt);
}
if (ls == 2 || rs == 2)
continue;
if (s[i] == 'S')
{
if (tag == 0)
lcnt++;
else
rcnt++;
}
else if (s[i] == 'R')
{
tag = 1 - tag;
if (tag == 0)
lcnt++;
else
rcnt++;
}
if (lcnt == 10 || lcnt >= 5 && lcnt >= rcnt + 2)
{
ls++;
lcnt = rcnt = 0;
}
else if (rcnt == 10 || rcnt >= 5 && rcnt >= lcnt + 2)
{
rs++;
lcnt = rcnt = 0;
}
}
}
G. Game Show
最大前缀和 签到
H. SBC's Hangar
每个数倍数差都在2以上
意思就是 从小到大排序后 大的那个的数量 小的所有加起来都取不到
用二进制表示是否取这个
因此可以输出最大的能表示的范围内的二进制情况
然后也能得到 最小的满足范围下界的二进制
对其中的式子进行数位dp
#define int ll
int a[MAXN];
int upper[MAXN];int n,k;
int dp[60][2][60];
ll dfs(int pos,int pre_num,int c,int flag){
int max_number;
if(pos<=0) return c==k;
if(!flag&&dp[pos][pre_num][c]!=-1) return dp[pos][pre_num][c];
if(flag) max_number=upper[pos];
else max_number=1;
ll ret=0;
for(int i=0;i<=max_number;i++){
ret+=dfs(pos-1,i,c+i,flag&&(i==max_number));
}
if(!flag) dp[pos][pre_num][c]=ret;
return ret;
}
void solve(){
cin>>n>>k;
for(int i=1;i<=n;i++) cin>>a[i];
sort(a+1,a+1+n);
int l,r;cin>>l>>r;
int tmp=r;
for(int i=n;i>=1;i--){
if(a[i]<=tmp){
upper[i]=1;
tmp-=a[i];
}
else upper[i]=0;
}
for(int i=0;i<=n;i++){
for(int j=0;j<=1;j++){
for(int x=0;x<=n;x++) dp[i][j][x]=-1;
}
}
int ans=dfs(n,0,0,1);
tmp=0;
int cnt=0;
for(int i=n;i>=1;i--){
int temp=0;
for(int j=1;j<i;j++){
temp+=a[j];
}
if(temp+tmp<l){
tmp+=a[i];
upper[i]=1;
cnt++;
}
else upper[i]=0;
}
for(int i=0;i<=n;i++){
for(int j=0;j<=1;j++){
for(int x=0;x<=n;x++) dp[i][j][x]=-1;
}
}
if(cnt==k&&tmp>=l) ans++;
ans-=dfs(n,0,0,1);
cout<<ans;
}
I. Interactivity
树dp 队友式子推对了但是用逆元的组合数就错了
N. Number Multiplication
套了个n1/4的分解质因数的板子就过了
就板子 不贴了 毛的
7. 2018-2019 ACM-ICPC Brazil Subregional Programming Contest
赛时CDEFIL 补题BG
B. Marbles
博弈
C. Pizza Cutter
扫描线 就逆序对那个
如果加了一条线多了a个交点 那么方块的个数多a+1
扫两遍就行
因为只有Li>Lj&&Ri<Rj的才有交点 很好统计
#define int ll
int t[MAXN];
int lowbit(int x) {
return x&-x;
}
ll getsum(int x) {
ll sum=0;
while(x) {
sum+=t[x];
x-=lowbit(x);
}
return sum;
}
void addv(int x,int val) {
while(x<MAXN) {
t[x]+=val;
x+=lowbit(x);
}
}
vector<int> X;
int getX(int x) {
int k=lower_bound(X.begin(),X.end(),x)-X.begin();
return k;
}
struct node{
int x,y;
}N[MAXN];
bool bj(node a,node b){
return a.x>b.x;
}
void solve() {
int x,y;
cin>>x>>y;
int n,m;cin>>n>>m;
for(int i=1;i<=n;i++){
cin>>N[i].x>>N[i].y;
X.push_back(N[i].x);
X.push_back(N[i].y);
}
X.push_back(inf*-1);
sort(X.begin(),X.end());
X.erase(unique(X.begin(),X.end()),X.end());
int ans=1;
sort(N+1,N+1+n,bj);
for(int i=1;i<=n;i++){
int a=N[i].x;
int b=N[i].y;
b=getX(b);
ans+=1+getsum(b);
addv(b,1);
}
memset(t,0,sizeof(t));
X.clear();
for(int i=1;i<=m;i++){
cin>>N[i].x>>N[i].y;
X.push_back(N[i].x);
X.push_back(N[i].y);
}
X.push_back(inf*-1);
sort(X.begin(),X.end());
X.erase(unique(X.begin(),X.end()),X.end());
sort(N+1,N+1+m,bj);
for(int i=1;i<=m;i++){
int a=N[i].x;
int b=N[i].y;
b=getX(b);
ans+=1+getsum(b);
addv(b,1);
}
ans+=n*m;
cout<<ans;
}
D. Unraveling Monty Hall
队友签到的
void solve()
{
// freopen("data.in.txt","r",stdin);
// freopen("data.out.txt","w",stdout);
int n, a, ans = 0;
cin >> n;
while (n--)
{
cin >> a;
if (a > 1)
ans++;
}
cout << ans;
}
E. Enigma
对每个字母扫 它的贡献值算在字符串的头上
计算有几个字符串位置的头贡献是0就行了
int len[MAXN];
void solve()
{
string a,b;cin>>a>>b;
int na=a.length(),nb=b.length();
b=" "+b;
a=" "+a;
int st=na-nb;
for(int i=1;i<=nb;i++){
for(int j=i;j<=st+i;j++){
if(a[j]==b[i]){
len[j-i+1]++;
// cout<<b[i]<<" "<<j-i+1<<"\n";
}
}
}
int ans=0;
for(int i=1;i<=st+1;i++){
if(len[i]==0) ans++;
}
cout<<ans;
}
F. Music Festival
每个舞会至少选一个人 表演时间不能重合 求最大贡献
状压dp
vector<array<int,3> >g[86405];
int f[86405][1100];
void solve(){
int n=read();
for(int i=1;i<=n;i++){
int k=read();
for(int j=1;j<=k;j++){
int x=read(),y=read(),w=read();
g[y].push_back((array<int,3>){x,w,i});
}
}
for(int i=1;i<=86400;i++){
for(int j=0;j<(1<<(n));j++){
f[i][j]=f[i-1][j];
for(auto it:g[i]){
int l=it[0],w=it[1],k=it[2]-1;
if(((j>>k)&1)&&(f[l][j-(1<<k)]>0))f[i][j]=max(f[i][j],f[l][j-(1<<k)]+w);
if((((j&(((1<<n)-1)-(1<<k)))==0))||(f[l][(j&(((1<<n)-1)-(1<<k)))]>0))f[i][j]=max(f[i][j],f[l][(j&(((1<<n)-1)-(1<<k)))]+w);
}
}
}
// cerr<<1<<'\n';
int ans=0;
for(int i=1;i<=86400;i++){
ans=max(ans,f[i][(1<<(n))-1]);
}
if(ans==0)cout<<-1<<'\n';
else cout<<ans<<'\n';
//puts(ans>0?"YES":"NO");
//puts(ans>0?"Yes":"No");
}
G. Gasoline
二分+网络流
不会写 队友补了
I. Switches
最多做两边就知道结果了
模拟一下
int aim[N], n, m, p[N];
vector<int> a[N];
bool check()
{
for (int i = 1; i <= m; i++)
{
if (aim[i] != p[i])
return false;
}
return true;
}
void solve()
{
// freopen("data.in.txt","r",stdin);
// freopen("data.out.txt","w",stdout);
cin >> n >> m;
int l;
cin >> l;
for (int i = 1; i <= l; i++)
{
int tp;
cin >> tp;
aim[tp] = 1;
}
for (int i = 1; i <= n; i++)
{
int num, tp;
cin >> num;
for (int j = 1; j <= num; j++)
{
cin >> tp;
a[i].push_back(tp);
}
}
int ans = 0;
for (int i = 1; i <= n * 2; i++)
{
int id = (i - 1) % n + 1;
for (auto pos : a[id])
p[pos] ^= 1;
ans++;
if (check())
{
cout << ans << endl;
return;
}
}
// for (int i = 1; i <= m; i++)
// cout << p[i] << ' ';
// cout << endl;
cout << -1 << endl;
}
J. Joining Capitals
听说是最小斯坦纳树 先学学
L. Subway Lines
树剖 区间0/1翻转 统计全数1的个数 就可以算出变成0的个数
听讲题发现做麻烦了
using namespace std;
#define int ll
int deep[MAXN],siz[MAXN],f[MAXN],hson[MAXN],dfn[MAXN],top[MAXN],cnt=0,rdfn[MAXN],rak[MAXN];
vector<int> adj[MAXN];
struct Info{
int sum;
};
Info operator +(const Info &a,const Info &b){
Info c;
c.sum=a.sum+b.sum;
return c;
};
struct node{
int lazy;
Info val;
}seg[MAXN<<2];
void up(int id){
seg[id].val=seg[id<<1].val+seg[id<<1|1].val;
}
void settag(int id,int l,int r,int tag){
seg[id].val.sum=r-l+1-seg[id].val.sum;
seg[id].lazy^=1;
}
void down(int id,int l,int r){
if(seg[id].lazy==0) return;
int mid=l+r>>1;
settag(id<<1,l,mid,seg[id].lazy);
settag(id<<1|1,mid+1,r,seg[id].lazy);
seg[id].lazy=0;
}
void build(int id,int l,int r){
if(l==r){
seg[id].val.sum=0;
seg[id].lazy=0;
return;
}
int mid=l+r>>1;
build(id<<1,l,mid);
build(id<<1|1,mid+1,r);
up(id);
}
void modify(int id,int l,int r,int ql,int qr,int val){
if(ql==l&&r==qr){
settag(id,l,r,val);
return;
}
down(id,l,r);
int mid=l+r>>1;
if(qr<=mid) modify(id<<1,l,mid,ql,qr,val);
else if(ql>mid) modify(id<<1|1,mid+1,r,ql,qr,val);
else{
modify(id<<1,l,mid,ql,mid,val);
modify(id<<1|1,mid+1,r,mid+1,qr,val);
}
up(id);
}
Info query(int id,int l,int r,int ql,int qr){
if(ql==l&&r==qr) return seg[id].val;
down(id,l,r);
int mid=l+r>>1;
if(qr<=mid) return query(id<<1,l,mid,ql,qr);
else if(ql>mid) return query(id<<1|1,mid+1,r,ql,qr);
else{
return query(id<<1,l,mid,ql,mid)+query(id<<1|1,mid+1,r,mid+1,qr);
}
}
void tree_build(int u,int fa,int dep){
deep[u]=dep;
siz[u]=1;
f[u]=fa;
hson[u]=0;
for(auto &v:adj[u]){
if(v==fa) continue;
tree_build(v,u,dep+1);
siz[u]+=siz[v];
if(hson[u]==0||siz[v]>siz[hson[u]]) hson[u]=v;
}
}
void tree_decom(int u,int t){
top[u]=t;
cnt++;
dfn[u]=cnt;
rak[cnt]=u;
if(hson[u]!=0){
tree_decom(hson[u],t);
for(auto &v:adj[u]){
if(hson[u]!=v&&v!=f[u]) tree_decom(v,v);
}
}
rdfn[u]=cnt;
}
int getlca(int u,int v){
while(top[u]!=top[v]){
if(deep[top[u]]>deep[top[v]]) u=f[top[u]];
else v=f[top[v]];
}
return deep[u]>deep[v]?v:u;
}int n,m;
void calc(int u,int v){
while(top[u]!=top[v]) {
if(deep[top[u]]>deep[top[v]]) {
modify(1,1,n,dfn[top[u]],dfn[u],1);
u=f[top[u]];
} else {
modify(1,1,n,dfn[top[v]],dfn[v],1);
v=f[top[v]];
}
}
if(dfn[v]<dfn[u]) swap(u,v);
modify(1,1,n,dfn[u],dfn[v],1);
// cout<<"* ";
// for(int i=1;i<=n;i++){
// cout<<query(1,1,n,i,i).sum<<" ";
// }
// cout<<"\n";
}
void solve()
{
cin>>n>>m;
for(int i=1;i<n;i++){
int u,v;cin>>u>>v;
adj[u].push_back(v);
adj[v].push_back(u);
}
tree_build(1,0,0);
tree_decom(1,1);
// for(int i=1;i<=n;i++) cout<<dfn[i]<<" ";
// for(int i=1;i<=n;i++) cout<<top[i]<<" ";
// cout<<"\n";
build(1,1,n);
while(m--){
int u,v,p,q;
cin>>u>>v;
calc(u,v);
int len1=deep[u]+deep[v]-deep[getlca(u,v)]*2+1;
cin>>p>>q;
calc(p,q);
int len2=deep[p]+deep[q]-deep[getlca(p,q)]*2+1;
int ans=len1+len2-query(1,1,n,1,n).sum;
ans/=2;
cout<<ans<<'\n';
calc(u,v);
calc(p,q);
}
}
M. Modifying SAT
赛时写的2-sat 好像是高斯消元 晚点补
8. 2020-2021 Winter Petrozavodsk Camp, Day 5: Almost Retired Dandelion Contest (XXI Open Cup, Grand Prix of Nizhny Novgorod)
赛时过题:GJM 补题A
A. Assignment Problem
回溯法 暴力搜索
赛场上没算明白不敢写
#include<bits/stdc++.h>
#define close std::ios::sync_with_stdio(false),cin.tie(0),cout.tie(0)
using namespace std;
typedef long long ll;
const ll MAXN = 3e5+7;
const ll mod = 1e9+7;
const ll inf = 0x3f3f3f3f;
int a[20][1050];
int f[MAXN];
int ans[MAXN];
int vis[MAXN];
int n,m;
void dfs(int p){
int q=0;
for(int i=1;i<=m;i++){
if(f[a[p][i]]==0){
q=a[p][i];
break;
}
}
f[q]=1;
ans[q]=1;
for(int i=1;i<=m;i++){
if(vis[i]) continue;
vis[i]=1;
dfs(i);
vis[i]=0;
}
f[q]=0;
return;
}
void solve(){
cin>>n>>m;
for(int i=1;i<=m;i++){
for(int j=1;j<=n;j++) cin>>a[i][j];
}
for(int i=1;i<=m;i++){
vis[i]=1;
dfs(i);
vis[i]=0;
}
int cnt=0;
for(int i=1;i<=n;i++){
if(ans[i]) cnt++;
}
cout<<cnt<<"\n";
for(int i=1;i<=n;i++){
if(ans[i])
cout<<i<<" ";
}
}
G. Remove the Prime
用n1/4分解质因数然后nim博弈 代码太长了不丢了
J. Increasing or Decreasing
先给它整体排序一遍 然后再从一遍开始一个一个对其 刚好n次
int n;
int a[N], p[N];
int pos[N];
struct ans
{
int l, r;
char ch;
} as[N];
int cnt = 0;
int cmp1(int &a, int &b)
{
return a > b;
}
void solve()
{
// freopen("data.in.txt","r",stdin);
// freopen("data.out.txt","w",stdout);
cin >> n;
for (int i = 1; i <= n; i++)
cin >> a[i];
as[++cnt] = {1, n, 'I'};
sort(a + 1, a + 1 + n);
for (int i = 1; i <= n; i++)
pos[a[i]] = i;
for (int i = 1; i <= n; i++)
cin >> p[i];
for (int i = n; i > 0; i--)
{
if (a[i] == p[i])
continue;
cnt++;
int l = pos[p[i]], r = i;
// cerr << l << ' ' << r << endl;
sort(a + l, a + 1 + r);
as[cnt].l = l;
as[cnt].r = r;
if (a[r] == p[i])
as[cnt].ch = 'I';
else
{
sort(a + l, a + 1 + r, cmp1);
as[cnt].ch = 'D';
}
for (int j = l; j <= r; j++)
pos[a[j]] = j;
// for (int i = 1; i <= n; i++)
// cout << a[i] << ' ';
// cout << endl;
}
cout << cnt << endl;
for (int i = 1; i <= cnt; i++)
cout << as[i].l << ' ' << as[i].r << ' ' << as[i].ch << endl;
}
M. Discrete Logarithm is a Joke
从最后一个数往前面跑 mod别写1e18+31 好像会爆ll
#include<bits/stdc++.h>
using namespace std;
#define int __int128
typedef long long ll;
const long long mod = 1000000000000000031;
int _power(int a,int b) {
int ans=1,res=a;
while(b) {
if(b&1)
ans=ans*res%mod;
res=res*res%mod;
b>>=1;
}
return ans%mod;
}
void cal() {
long long n;
cin>>n;
long long st=300;
for(int i=1000000-1; i>=n; i--) {
st=_power(42,st);
}
cout<<st<<'\n';
}