A A. A Good Problem
A good problem should have a concise statement.
You are given an array a of length n, initially filled with zeros, and another array b of length n. Your goal
is to transform array a into array b. You can perform the following two types of operations:
• 1 x: Add 1 to all elements in a that are equal to x.
• 2 x: Add 1 to the element in a at index x.
You can perform no more than 20 000 operations.
分治,考虑最极端情况为 1 , 2 , ⋯ , n 1,2,\cdots,n 1,2,⋯,n
- 先把 [ n / 2 + 1 , n ] [n/2+1,n] [n/2+1,n]区间的数变为 1 1 1
- 把 [ n / 2 + 1 , n ] [n/2+1,n] [n/2+1,n]区间的数变为 n / 2 + 1 n/2+1 n/2+1
- 处理 [ n / 2 + 1 , n ] [n/2+1,n] [n/2+1,n]区间
- 处理 [ 1 , n / 2 ] [1,n/2] [1,n/2]区间
#include<bits/stdc++.h>
using namespace std;
#define For(i,n) for(int i=1;i<=n;i++)
#define Fork(i,k,n) for(int i=k;i<=n;i++)
#define ForkD(i,k,n) for(int i=n;i>=k;i--)
#define Rep(i,n) for(int i=0;i<n;i++)
#define ForD(i,n) for(int i=n;i;i--)
#define RepD(i,n) for(int i=n;i>=0;i--)
#define Forp(x) for(int p=pre[x];p;p=next[p])
#define Forpiter(x) for(int &p=iter[x];p;p=next[p])
#define Lson (o<<1)
#define Rson ((o<<1)+1)
#define MEM(a) memset(a,0,sizeof(a));
#define MEMI(a) memset(a,0x3f,sizeof(a));
#define MEMi(a) memset(a,128,sizeof(a));
#define MEMx(a,b) memset(a,b,sizeof(a));
#define INF (0x3f3f3f3f)
#define F (1000000007)
#define pb push_back
#define mp make_pair
#define fi first
#define se second
#define vi vector<int>
#define pi pair<int,int>
#define SI(a) ((a).size())
#define Pr(kcase,ans) printf("Case #%d: %lld\n",kcase,ans);
#define PRi(a,n) For(i,n-1) cout<<a[i]<<' '; cout<<a[n]<<endl;
#define PRi2D(a,n,m) For(i,n) { \
For(j,m-1) cout<<a[i][j]<<' ';\
cout<<a[i][m]<<endl; \
}
#pragma comment(linker, "/STACK:102400000,102400000")
#define ALL(x) (x).begin(),(x).end()
#define gmax(a,b) a=max(a,b);
#define gmin(a,b) a=min(a,b);
typedef long long ll;
typedef long double ld;
typedef unsigned long long ull;
ll mul(ll a,ll b){return (a*b)%F;}
ll add(ll a,ll b){return (a+b)%F;}
ll sub(ll a,ll b){return ((a-b)%F+F)%F;}
void upd(ll &a,ll b){a=(a%F+b%F)%F;}
inline int read()
{
int x=0,f=1; char ch=getchar();
while(!isdigit(ch)) {if (ch=='-') f=-1; ch=getchar();}
while(isdigit(ch)) { x=x*10+ch-'0'; ch=getchar();}
return x*f;
}
int n,a[1010];
pi pa[1010];
vector<pi > ans;
void work(int l,int r,int now) {
if(l>r) return;
while(l<=r && pa[l].fi==now) ++l;
if(l>r) return;
int m=l+r>>1;
if(l==r) {
Fork(i,l,r) {
ans.pb(mp(2,pa[i].se));
}
Fork(j,now+1,pa[l].fi-1) ans.pb(mp(1,j));
return;
}
if(m+1<=r) {
Fork(i,m+1,r) {
ans.pb(mp(2,pa[i].se));
}
Fork(j,now+1,pa[m+1].fi-1) ans.pb(mp(1,j));
work(m+1,r,pa[m+1].fi);
}
if(l<=m) {
work(l,m,now);
}
}
int b[1010]={};
int main()
{
n=read();
For(i,n) a[i]=read();
For(i,n) pa[i]=mp(a[i],i);
sort(pa+1,pa+1+n);
work(1,n,0);
for(auto i:ans) {
if(i.fi==1) {
For(j,n) if(b[j]==i.se) ++b[j];
}else{
b[i.se]++;
}
}
// For(i,n) if(a[i]!=b[i]) cout<<"z";
cout<<SI(ans)<<endl;
for(auto i:ans) cout<<i.fi<<' '<<i.se<<endl;
return 0;
}
F Gift
Given an undirected graph with n vertices and n edges, you need to calculate how many ways there are to choose a vertex p and an edge (x, y) such that, after removing the edge (x, y), the graph becomes a
tree, and when this tree is rooted at p, each node has no more than 3 children. It is guaranteed that there
is at least one possible plan
找出环,然后枚举删的边
#include<bits/stdc++.h>
using namespace std;
#define For(i,n) for(int i=1;i<=n;i++)
#define Fork(i,k,n) for(int i=k;i<=n;i++)
#define ForkD(i,k,n) for(int i=n;i>=k;i--)
#define Rep(i,n) for(int i=0;i<n;i++)
#define ForD(i,n) for(int i=n;i;i--)
#define RepD(i,n) for(int i=n;i>=0;i--)
#define Forp(x) for(int p=pre[x];p;p=next[p])
#define Forpiter(x) for(int &p=iter[x];p;p=next[p])
#define Lson (o<<1)
#define Rson ((o<<1)+1)
#define MEM(a) memset(a,0,sizeof(a));
#define MEMI(a) memset(a,0x3f,sizeof(a));
#define MEMi(a) memset(a,128,sizeof(a));
#define MEMx(a,b) memset(a,b,sizeof(a));
#define INF (0x3f3f3f3f)
#define F (1000000007)
#define pb push_back
#define mp make_pair
#define fi first
#define se second
#define vi vector<int>
#define pi pair<int,int>
#define SI(a) ((a).size())
#define Pr(kcase,ans) printf("Case #%d: %lld\n",kcase,ans);
#define PRi(a,n) For(i,n-1) cout<<a[i]<<' '; cout<<a[n]<<endl;
#define PRi2D(a,n,m) For(i,n) { \
For(j,m-1) cout<<a[i][j]<<' ';\
cout<<a[i][m]<<endl; \
}
#pragma comment(linker, "/STACK:102400000,102400000")
#define ALL(x) (x).begin(),(x).end()
#define gmax(a,b) a=max(a,b);
#define gmin(a,b) a=min(a,b);
typedef long long ll;
typedef long double ld;
typedef unsigned long long ull;
ll mul(ll a,ll b){return (a*b)%F;}
ll add(ll a,ll b){return (a+b)%F;}
ll sub(ll a,ll b){return ((a-b)%F+F)%F;}
void upd(ll &a,ll b){a=(a%F+b%F)%F;}
inline int read()
{
int x=0,f=1; char ch=getchar();
while(!isdigit(ch)) {if (ch=='-') f=-1; ch=getchar();}
while(isdigit(ch)) { x=x*10+ch-'0'; ch=getchar();}
return x*f;
}
#define MAXN (212345)
int n,deg[MAXN]={},deg2[MAXN]={};
vi v[MAXN];
int c[MAXN]={};
int main()
{
// freopen("f.in","r",stdin);
// freopen(".out","w",stdout);
n=read();
For(i,n) {
int x=read(),y=read();
v[x].pb(y); v[y].pb(x);
deg[x]++;deg[y]++;
}
queue<int> q;
For(i,n) if(deg[i]==1) q.push(i);
For(i,n) deg2[i]=deg[i],c[deg[i]]++;
while(!q.empty()) {
int x=q.front();
for(auto y:v[x]) {
if(deg[y]) {
--deg[y];
if(deg[y]==1) q.push(y);
}
}
q.pop();
deg[x]=0;
}
ll ans=0;
For(i,n) for(auto j:v[i]) if(i<j && deg[i]>0 && deg[j]>0 ){
c[deg2[i]]--,c[deg2[j]]--;
c[deg2[i]-1]++,c[deg2[j]-1]++;
if(!c[5]) {
ans+=n-c[5]-c[4];
}
c[deg2[i]]++,c[deg2[j]]++;
c[deg2[i]-1]--,c[deg2[j]-1]--;
}
cout<<ans<<endl;
return 0;
}
G Gene
经典trick字符串双hash,二分找下一个不同的位置
#include<bits/stdc++.h>
using namespace std;
#define For(i,n) for(int i=1;i<=n;i++)
#define Fork(i,k,n) for(int i=k;i<=n;i++)
#define ForkD(i,k,n) for(int i=n;i>=k;i--)
#define Rep(i,n) for(int i=0;i<n;i++)
#define ForD(i,n) for(int i=n;i;i--)
#define RepD(i,n) for(int i=n;i>=0;i--)
#define Forp(x) for(int p=pre[x];p;p=next[p])
#define Forpiter(x) for(int &p=iter[x];p;p=next[p])
#define Lson (o<<1)
#define Rson ((o<<1)+1)
#define MEM(a) memset(a,0,sizeof(a));
#define MEMI(a) memset(a,0x3f,sizeof(a));
#define MEMi(a) memset(a,128,sizeof(a));
#define MEMx(a,b) memset(a,b,sizeof(a));
#define INF (0x3f3f3f3f)
#define F (1000000007)
#define pb push_back
#define mp make_pair
#define fi first
#define se second
#define vi vector<int>
#define pi pair<int,int>
#define SI(a) ((a).size())
#define Pr(kcase,ans) printf("Case #%d: %lld\n",kcase,ans);
#define PRi(a,n) For(i,n-1) cout<<a[i]<<' '; cout<<a[n]<<endl;
#define PRi2D(a,n,m) For(i,n) { \
For(j,m-1) cout<<a[i][j]<<' ';\
cout<<a[i][m]<<endl; \
}
#pragma comment(linker, "/STACK:102400000,102400000")
#define ALL(x) (x).begin(),(x).end()
#define gmax(a,b) a=max(a,b);
#define gmin(a,b) a=min(a,b);
typedef long long ll;
typedef long double ld;
typedef unsigned long long ull;
ll mul(ll a,ll b){return (a*b)%F;}
ll add(ll a,ll b){return (a+b)%F;}
ll sub(ll a,ll b){return ((a-b)%F+F)%F;}
void upd(ll &a,ll b){a=(a%F+b%F)%F;}
inline int read()
{
int x=0,f=1; char ch=getchar();
while(!isdigit(ch)) {if (ch=='-') f=-1; ch=getchar();}
while(isdigit(ch)) { x=x*10+ch-'0'; ch=getchar();}
return x*f;
}
const int L = 6e4 + 5;
const int HASH_CNT = 2;
int hashBase[HASH_CNT] = {29, 31};
int hashMod[HASH_CNT] = {int(1e9 + 9), 998244353};
struct StringWithHash {
char s[L];
int ls;
int hsh[HASH_CNT][L];
int pwMod[HASH_CNT][L];
void init() { // 初始化
ls = 0;
for (int i = 0; i < HASH_CNT; ++i) {
hsh[i][0] = 0;
pwMod[i][0] = 1;
}
}
StringWithHash() { init(); }
void extend(char c) {
s[++ls] = c; // 记录字符数和每一个字符
for (int i = 0; i < HASH_CNT; ++i) { // 双哈希的预处理
pwMod[i][ls] =
1ll * pwMod[i][ls - 1] * hashBase[i] % hashMod[i]; // 得到b^ls
hsh[i][ls] = (1ll * hsh[i][ls - 1] * hashBase[i] + c) % hashMod[i];
}
}
vector<int> getHash(int l, int r) { // 得到哈希值 字符串从1开始计数
vector<int> res(HASH_CNT, 0);
for (int i = 0; i < HASH_CNT; ++i) {
int t =
(hsh[i][r] - 1ll * hsh[i][l - 1] * pwMod[i][r - l + 1]) % hashMod[i];
t = (t + hashMod[i]) % hashMod[i];
res[i] = t;
}
return res;
}
};
bool equal(const vector<int> &h1, const vector<int> &h2) {
assert(h1.size() == h2.size());
for (unsigned i = 0; i < h1.size(); i++)
if (h1[i] != h2[i]) return false;
return true;
}
int n,q,m,k;
StringWithHash s[310],t;
int calc(int i) {
int l=1,K=k;
do{
int L=l,R=m,ans=L-1;
while(L<=R) {
int M=L+R>>1;
if(equal(t.getHash(L, M),s[i].getHash(L, M)) ) {
ans=M,L=M+1;
}else R=M-1;
}
// cout<<"|"<<ans<<'|'<<" ";
if(ans==m) return 1;
if(K==0) return 0;
l=ans+2;
if(l>m) return 1;
--K;
}while(1);
return 0;
}
int main()
{
// freopen("G.in","r",stdin);
// freopen(".out","w",stdout);
cin>>n>>q>>m>>k;
For(i,n) {
string st;cin>>st;
Rep(j,m) s[i].extend(st[j]);
}
For(i,q) {
string st;cin>>st;
t.init();
Rep(j,m) t.extend(st[j]);
int ans=0;
For(j,n) {
int p=calc(j);
// cout<<p;
ans+=p;
}
cout<<ans<<endl;
}
return 0;
}