A - Two distinct points
直接循环就行了,因为根本跑不满 n 2 n^2 n2
#include <iostream>
#include <map>
#include <ctime>
#include <vector>
#include <climits>
#include <algorithm>
#include <random>
#include <cstring>
#include <cstdio>
#include <map>
#include <set>
#include <bitset>
#include <queue>
#define inf 0x3f3f3f3f
#define IOS ios_base::sync_with_stdio(0); cin.tie(0);
#define rep(i, a, n) for(register int i = a; i <= n; ++ i)
#define per(i, a, n) for(register int i = n; i >= a; -- i)
//#define ONLINE_JUDGE
using namespace std;
typedef long long ll;
const int mod=1e9+7;
template<typename T>void write(T x)
{
if(x<0)
{
putchar('-');
x=-x;
}
if(x>9)
{
write(x/10);
}
putchar(x%10+'0');
}
template<typename T> void read(T &x)
{
x = 0;char ch = getchar();ll f = 1;
while(!isdigit(ch)){if(ch == '-')f*=-1;ch=getchar();}
while(isdigit(ch)){x = x*10+ch-48;ch=getchar();}x*=f;
}
int gcd(int a,int b){return b==0?a:gcd(b,a%b);}
int lcm(int a,int b){return a/gcd(a,b)*b;};
ll ksm(ll a,ll n){//看是否要mod
ll ans=1;
while(n){
if(n&1) ans=(ans*a)%mod;
a=a*a%mod;
n>>=1;
}
return ans%mod;
}
//==============================================================
int q,l1,r1,l2,r2;
#define pii pair<int,int>
pii solve(){
int a=l1;
rep(i,l1,r1){
rep(j,l2,r2){
if(i!=j){
return make_pair(i,j);
}
}
}
}
int main()
{
#ifndef ONLINE_JUDGE
freopen("in.txt","r",stdin);
freopen("out.txt","w",stdout);
#endif
//clock_t c1 = clock();
//===========================================================
read(q);
while(q--){
read(l1),read(r1),read(l2),read(r2);
auto ans=solve();
write(ans.first),putchar(' '),write(ans.second),putchar('\n');
}
//===========================================================
//std::cerr << "Time:" << clock() - c1 << "ms" << std::endl;
return 0;
}
B - Divisors of Two Integers
因为含有1*本身这对因数,所以,最大的那个数肯定事其中一个,所以,我们可以找出最大的那个数,找出它的所有因数,用这些因数排除掉序列中原有的,剩下的就是另一个数的因数了,之后,依旧找出最大的就好了。
#include <iostream>
#include <map>
#include <ctime>
#include <vector>
#include <climits>
#include <algorithm>
#include <random>
#include <cstring>
#include <cstdio>
#include <map>
#include <set>
#include <bitset>
#include <queue>
#define inf 0x3f3f3f3f
#define IOS ios_base::sync_with_stdio(0); cin.tie(0);
#define rep(i, a, n) for(register int i = a; i <= n; ++ i)
#define per(i, a, n) for(register int i = n; i >= a; -- i)
//#define ONLINE_JUDGE
using namespace std;
typedef long long ll;
const int mod=1e9+7;
template<typename T>void write(T x)
{
if(x<0)
{
putchar('-');
x=-x;
}
if(x>9)
{
write(x/10);
}
putchar(x%10+'0');
}
template<typename T> void read(T &x)
{
x = 0;char ch = getchar();ll f = 1;
while(!isdigit(ch)){if(ch == '-')f*=-1;ch=getchar();}
while(isdigit(ch)){x = x*10+ch-48;ch=getchar();}x*=f;
}
int gcd(int a,int b){return b==0?a:gcd(b,a%b);}
int lcm(int a,int b){return a/gcd(a,b)*b;};
ll ksm(ll a,ll n){//看是否要mod
ll ans=1;
while(n){
if(n&1) ans=(ans*a)%mod;
a=a*a%mod;
n>>=1;
}
return ans%mod;
}
//==============================================================
int n,d[130];
#define pii pair<int,int>
vector<int> pos[2];
map<int,int> mark;
int vis[130];
pii solve(){
int x=d[n];
rep(i,1,sqrt(x)){
if(x%i==0){
mark[i]++;
if(x/i!=i) mark[x/i]++;
}
}
rep(i,1,n){
if(mark[d[i]]){
vis[i]=1;
mark[d[i]]--;
}
}
int y=0;
rep(i,1,n){
if(vis[i]==0){
y=max(y,d[i]);
}
}
return make_pair(x,y);
}
int main()
{
#ifndef ONLINE_JUDGE
freopen("in.txt","r",stdin);
freopen("out.txt","w",stdout);
#endif
//clock_t c1 = clock();
//===========================================================
read(n);
rep(i,1,n) read(d[i]);
sort(d+1,d+1+n);
auto ans=solve();
write(ans.first),putchar(' '),write(ans.second),putchar('\n');
//===========================================================
//std::cerr << "Time:" << clock() - c1 << "ms" << std::endl;
return 0;
}
C - Nice Garland
根据mod3的结果把下标分成三类(为0,1,2)的,题目要求可知,同一种字母的下标mod3的结果必须相同,又因为必须填满,所以只能说0,1,2的各分一种字母,所以,这个排列一定是全排列的循环的一部分,所以,直接枚举RGB的全排列匹配即可。
#include <iostream>
#include <map>
#include <ctime>
#include <vector>
#include <climits>
#include <algorithm>
#include <random>
#include <cstring>
#include <cstdio>
#include <map>
#include <set>
#include <bitset>
#include <queue>
#define inf 0x3f3f3f3f
#define IOS ios_base::sync_with_stdio(0); cin.tie(0);
#define rep(i, a, n) for(register int i = a; i <= n; ++ i)
#define per(i, a, n) for(register int i = n; i >= a; -- i)
//#define ONLINE_JUDGE
using namespace std;
typedef long long ll;
const int mod=1e9+7;
template<typename T>void write(T x)
{
if(x<0)
{
putchar('-');
x=-x;
}
if(x>9)
{
write(x/10);
}
putchar(x%10+'0');
}
template<typename T> void read(T &x)
{
x = 0;char ch = getchar();ll f = 1;
while(!isdigit(ch)){if(ch == '-')f*=-1;ch=getchar();}
while(isdigit(ch)){x = x*10+ch-48;ch=getchar();}x*=f;
}
int gcd(int a,int b){return b==0?a:gcd(b,a%b);}
int lcm(int a,int b){return a/gcd(a,b)*b;};
ll ksm(ll a,ll n){//看是否要mod
ll ans=1;
while(n){
if(n&1) ans=(ans*a)%mod;
a=a*a%mod;
n>>=1;
}
return ans%mod;
}
//==============================================================
const int maxn=2e5+100;
char pos[10];
char str[maxn];
int n;
int solve(){
int p=0;
int cnt=0;
rep(i,0,n-1){
if(str[i]!=pos[p]){
cnt++;
}
p++;
p%=3;
}
return cnt;
}
vector<char> save;
int main()
{
#ifndef ONLINE_JUDGE
freopen("in.txt","r",stdin);
freopen("out.txt","w",stdout);
#endif
//clock_t c1 = clock();
//===========================================================
pos[0]='R',pos[1]='G',pos[2]='B';
int ans=inf;
read(n);
scanf("%s",str);
sort(pos,pos+3);
do{
int res=solve();
//cerr<<res<<" "<<pos<<endl;
if(res<ans){
ans=res;
save.clear();
rep(i,0,2){
save.push_back(pos[i]);
}
}
//ans=min(ans,solve());
}while(next_permutation(pos,pos+3));
int p=0;
write(ans),putchar('\n');
while(p<n){
putchar(save[p%3]);p++;
}
//===========================================================
//std::cerr << "Time:" << clock() - c1 << "ms" << std::endl;
return 0;
}
D - Diverse Garland
如果是一道搜索的话可以直接暴力枚举,由于数据范围较大,所以考虑记忆化搜索(DP)。因为状态转移只和相邻的字母有关,所以,我们状态需要记录结尾位置的字符(我们hash为1,2,3),子问题为开头位置为i的开头字符为j的后缀字符为Diverse Garland的最小修改次数,状态为dp[i][j],之后按照理解转移就行了。记得记路径
#include <iostream>
#include <map>
#include <ctime>
#include <vector>
#include <climits>
#include <algorithm>
#include <random>
#include <cstring>
#include <cstdio>
#include <map>
#include <set>
#include <bitset>
#include <queue>
#define inf 0x3f3f3f3f
#define IOS ios_base::sync_with_stdio(0); cin.tie(0);
#define rep(i, a, n) for(register int i = a; i <= n; ++ i)
#define per(i, a, n) for(register int i = n; i >= a; -- i)
//#define ONLINE_JUDGE
using namespace std;
typedef long long ll;
const int mod=1e9+7;
template<typename T>void write(T x)
{
if(x<0)
{
putchar('-');
x=-x;
}
if(x>9)
{
write(x/10);
}
putchar(x%10+'0');
}
template<typename T> void read(T &x)
{
x = 0;char ch = getchar();ll f = 1;
while(!isdigit(ch)){if(ch == '-')f*=-1;ch=getchar();}
while(isdigit(ch)){x = x*10+ch-48;ch=getchar();}x*=f;
}
int gcd(int a,int b){return b==0?a:gcd(b,a%b);}
int lcm(int a,int b){return a/gcd(a,b)*b;};
ll ksm(ll a,ll n){//????mod
ll ans=1;
while(n){
if(n&1) ans=(ans*a)%mod;
a=a*a%mod;
n>>=1;
}
return ans%mod;
}
//==============================================================
const int maxn=2e5+100;
char str[maxn];
int n;
#define pis pair<int,string>
map<char,int> re;
int dp[maxn][5];
#define pii pair<int,int>
pii pre[maxn][5];
void search(int pos){
if(pos==n){
rep(i,1,3){
dp[pos][i]=(re[str[pos]]!=i);
}
return;
}
search(pos+1);
rep(i,1,3){
rep(j,1,3){
if(i==j) continue;
else{
if(i==re[str[pos]]){
if(dp[pos][i]>dp[pos+1][j]){
dp[pos][i]=dp[pos+1][j];
pre[pos][i]=make_pair(pos+1,j);
}
}
else{
if(dp[pos][i]>dp[pos+1][j]+1){
dp[pos][i]=dp[pos+1][j]+1;
pre[pos][i]=make_pair(pos+1,j);
}
}
}
}
}
}
int solve(){
search(1);
return min(dp[1][1],min(dp[1][2],dp[1][3]));
}
void get_path(int pos,int con){
auto next=pre[pos][con];
if(con==1) putchar('R');
if(con==2) putchar('G');
if(con==3) putchar('B');
if(next.second==0) return;
get_path(next.first,next.second);
}
int main()
{
#ifndef ONLINE_JUDGE
freopen("in.txt","r",stdin);
freopen("out.txt","w",stdout);
#endif
//clock_t c1 = clock();
//===========================================================
read(n);scanf("%s",str+1);
memset(dp,inf,sizeof(dp));
re['R']=1;
re['G']=2;
re['B']=3;
int ans=solve();
write(ans),putchar('\n');
int a=1,b=1;
rep(i,2,3){
if(dp[1][i]<dp[a][b]){
a=1,b=i;
}
}
get_path(a,b);
//===========================================================
//std::cerr << "Time:" << clock() - c1 << "ms" << std::endl;
return 0;
}
E1 - Array and Segments (Easy version)
需要想到的是选定一个最大值(最小值也可)的位置,然后把不减少这个最大值的所有范围都给用上,在求出最小值,然后筛选出最大的差值,记录这个过程就行了。因为数据范围不大,所以维护最小值可以用差分+前缀和进行,方便区间修改。
#include <iostream>
#include <map>
#include <ctime>
#include <vector>
#include <climits>
#include <algorithm>
#include <random>
#include <cstring>
#include <cstdio>
#include <map>
#include <set>
#include <bitset>
#include <queue>
#define inf 0x3f3f3f3f
#define IOS ios_base::sync_with_stdio(0); cin.tie(0);
#define rep(i, a, n) for(register int i = a; i <= n; ++ i)
#define per(i, a, n) for(register int i = n; i >= a; -- i)
//#define ONLINE_JUDGE
using namespace std;
typedef long long ll;
const int mod=1e9+7;
template<typename T>void write(T x)
{
if(x<0)
{
putchar('-');
x=-x;
}
if(x>9)
{
write(x/10);
}
putchar(x%10+'0');
}
template<typename T> void read(T &x)
{
x = 0;char ch = getchar();ll f = 1;
while(!isdigit(ch)){if(ch == '-')f*=-1;ch=getchar();}
while(isdigit(ch)){x = x*10+ch-48;ch=getchar();}x*=f;
}
int gcd(int a,int b){return b==0?a:gcd(b,a%b);}
int lcm(int a,int b){return a/gcd(a,b)*b;};
ll ksm(ll a,ll n){//¿´ÊÇ·ñÒªmod
ll ans=1;
while(n){
if(n&1) ans=(ans*a)%mod;
a=a*a%mod;
n>>=1;
}
return ans%mod;
}
//==============================================================
const int maxn=3e2+100;
int n,m,a[maxn],l[maxn],r[maxn];
int save[maxn];
int in_cal[maxn];
vector<int> tmp;
vector<int> path;
bool check(int maxp,int pos){
return l[pos]<=maxp&&r[pos]>=maxp;
}
int cal(){
memcpy(in_cal,save,sizeof(in_cal));
rep(i,0,int(tmp.size())-1){
in_cal[l[tmp[i]]]--,in_cal[r[tmp[i]]+1]++;
}
int ma=-inf,mi=inf;
int now=0;
rep(i,1,n){
now+=in_cal[i];
ma=max(ma,now),mi=min(mi,now);
}
return ma-mi;
}
int solve(){
int ans=0;
rep(i,1,n){
rep(j,1,m){
if(!check(i,j)){
tmp.push_back(j);
}
}
int res=cal();
if(res>ans){
ans=res;
path=tmp;
}
tmp.clear();
}
return ans;
}
int main()
{
#ifndef ONLINE_JUDGE
freopen("in.txt","r",stdin);
freopen("out.txt","w",stdout);
#endif
//clock_t c1 = clock();
//===========================================================
read(n),read(m);
rep(i,1,n) read(a[i]);
per(i,1,n){
save[i]=a[i]-a[i-1];
}
rep(i,1,m){
read(l[i]),read(r[i]);
}
int ans=solve();
write(ans),putchar('\n');
write(path.size()),putchar('\n');
rep(i,0,int(path.size())-1){
if(i) putchar(' ');
write(path[i]);
}
putchar('\n');
//===========================================================
//std::cerr << "Time:" << clock() - c1 << "ms" << std::endl;
return 0;
}
E2 - Array and Segments (Hard version)
困难版的n范围变大了,所以用差分+前缀和O(n)维护最值已经不行了,所以,维护最值,支持修改,要用线段树。这里还有个优化才能过:我们选定i-1为最小值位置,我们添加了包含i-1位置的所有区间,这里面有些是包括了i位置的,那么,下次选定i位置为最小的时候,就不用把包含i位置的还原,所以,我们需要根据左右区间,对这些区间进行分类处理,方便每次还原操作。
#pragma GCC optimize(2)
#include <iostream>
#include <map>
#include <ctime>
#include <vector>
#include <climits>
#include <algorithm>
#include <random>
#include <cstring>
#include <cstdio>
#include <map>
#include <set>
#include <bitset>
#include <queue>
#define inf 0x3f3f3f3f
#define IOS ios_base::sync_with_stdio(0); cin.tie(0);
#define rep(i, a, n) for(register int i = a; i <= n; ++ i)
#define per(i, a, n) for(register int i = n; i >= a; -- i)
//#define ONLINE_JUDGE
using namespace std;
typedef long long ll;
const int mod=1e9+7;
template<typename T>void write(T x)
{
if(x<0)
{
putchar('-');
x=-x;
}
if(x>9)
{
write(x/10);
}
putchar(x%10+'0');
}
template<typename T> void read(T &x)
{
x = 0;char ch = getchar();ll f = 1;
while(!isdigit(ch)){if(ch == '-')f*=-1;ch=getchar();}
while(isdigit(ch)){x = x*10+ch-48;ch=getchar();}x*=f;
}
int gcd(int a,int b){return b==0?a:gcd(b,a%b);}
int lcm(int a,int b){return a/gcd(a,b)*b;};
ll ksm(ll a,ll n){//¿´ÊÇ·ñÒªmod
ll ans=1;
while(n){
if(n&1) ans=(ans*a)%mod;
a=a*a%mod;
n>>=1;
}
return ans%mod;
}
//==============================================================
#define int ll
#define lson (rt<<1)
#define rson (rt<<1|1)
const int maxn=1e5+100;
int n,m;
struct seg{
int l,r;
seg(int ls,int rr){
l=ls;
r=rr;
}
};
vector<seg> da;
struct node{
int l,r,val,lazy;
}tree[maxn<<2];
inline void push_up(int rt){
tree[rt].val=max(tree[lson].val,tree[rson].val);
}
inline void push_down(int rt){
if(tree[rt].lazy){
tree[lson].val+=tree[rt].lazy;
tree[rson].val+=tree[rt].lazy;
tree[lson].lazy+=tree[rt].lazy;
tree[rson].lazy+=tree[rt].lazy;
tree[rt].lazy=0;
return ;
}
}
void build(int l,int r,int rt){
tree[rt].l=l,tree[rt].r=r;
if(l==r) {read(tree[rt].val);return;}
int m=(l+r)>>1;
build(l,m,lson);
build(m+1,r,rson);
push_up(rt);
}
void modify(int ql,int qr,int rt,int val){
int l=tree[rt].l,r=tree[rt].r;
if(ql<=l&&r<=qr){
tree[rt].val+=val;
tree[rt].lazy+=val;
return ;
}
push_down(rt);
int m=(l+r)>>1;
if(ql<=m) modify(ql,qr,lson,val);
if(qr>m) modify(ql,qr,rson,val);
push_up(rt);
}
inline int query(int ql,int qr,int rt){
int l=tree[rt].l,r=tree[rt].r;
if(ql<=l&&r<=qr){
return tree[rt].val;
}
push_down(rt);
int m=(l+r)>>1;
int res=-inf;
if(ql<=m) res=max(res,query(ql,qr,lson));
if(qr>m) res=max(res,query(ql,qr,rson));
return res;
}
#define pii pair<int,int>
vector<int> cntl[maxn],cntr[maxn];
vector<int> save;
bool check(int pos,int tar){
return da[tar].l<=pos&&pos<=da[tar].r;
}
inline pii solve(){
int ans=0;
int tar=-1;
rep(i,1,n){
rep(j,0,int(cntl[i].size())-1){
modify(da[cntl[i][j]].l,da[cntl[i][j]].r,1,-1);
//tmp.push_back(cntl[i][j]);
}
int ma=query(1,n,1);
int mi=query(i,i,1);
if(ma-mi>ans){
ans=ma-mi;
tar=i;
//con=tmp;
}
rep(j,0,int(cntr[i].size())-1){
modify(da[cntr[i][j]].l,da[cntr[i][j]].r,1,1);
}
}
return make_pair(ans,tar);
}
signed main()
{
#ifndef ONLINE_JUDGE
freopen("in.txt","r",stdin);
freopen("out.txt","w",stdout);
#endif
//clock_t c1 = clock();
//===========================================================
read(n),read(m);
build(1,n,1);
da.push_back(seg(0,0));
rep(i,1,m){
int l,r;read(l),read(r);
da.push_back(seg(l,r));
cntl[l].push_back(i);
cntr[r].push_back(i);
}
auto ans=solve();
write(ans.first),putchar('\n');
int cnt=0;
//cerr<<ans.second<<endl;
rep(i,1,m){
if(check(ans.second,i)){
cnt++;
save.push_back(i);
}
}
write(cnt),putchar('\n');
rep(i,0,int(save.size())-1){
if(i) putchar(' ');
write(save[i]);
}
//===========================================================
//std::cerr << "Time:" << clock() - c1 << "ms" << std::endl;
return 0;
}
F - MST Unification
思考最小生成树出现多解的原因:w相同的几条边都能够达到相同的效果,因此,我们考虑在克鲁斯卡尔求最小生成树的同时,首先,找出所有权值相同的,并且现在能起到连接不同连通块作用的边,然后,在merge的同时,查看这些边里边是否有刚刚被merge了的,有的话就需要数目–(和前面的边作用重复了),之后统计数目的总数就行了。
#pragma GCC optimize(2)
#include <iostream>
#include <map>
#include <ctime>
#include <vector>
#include <climits>
#include <algorithm>
#include <random>
#include <cstring>
#include <cstdio>
#include <map>
#include <set>
#include <bitset>
#include <queue>
#define inf 0x3f3f3f3f
#define IOS ios_base::sync_with_stdio(0); cin.tie(0);
#define rep(i, a, n) for(register int i = a; i <= n; ++ i)
#define per(i, a, n) for(register int i = n; i >= a; -- i)
//#define ONLINE_JUDGE
using namespace std;
typedef long long ll;
const int mod=1e9+7;
template<typename T>void write(T x)
{
if(x<0)
{
putchar('-');
x=-x;
}
if(x>9)
{
write(x/10);
}
putchar(x%10+'0');
}
template<typename T> void read(T &x)
{
x = 0;char ch = getchar();ll f = 1;
while(!isdigit(ch)){if(ch == '-')f*=-1;ch=getchar();}
while(isdigit(ch)){x = x*10+ch-48;ch=getchar();}x*=f;
}
int gcd(int a,int b){return b==0?a:gcd(b,a%b);}
int lcm(int a,int b){return a/gcd(a,b)*b;};
ll ksm(ll a,ll n){//¿´ÊÇ·ñÒªmod
ll ans=1;
while(n){
if(n&1) ans=(ans*a)%mod;
a=a*a%mod;
n>>=1;
}
return ans%mod;
}
//==============================================================
const int maxn=2e5+100;
int n,m;
struct Edge{
int u,v,w;
Edge(int uu,int vv,int ww){
u=uu;
v=vv;
w=ww;
}
};
vector<Edge> da;
auto cmp=[](const Edge&a,const Edge&b){
return a.w<b.w;
};
//priority_queue<Edge,vector<Edge>,decltype(cmp)> que(cmp);
int s[maxn];
int find(int x){
if(s[x]==x) return x;
int r=x;
while(s[r]!=r) r=s[r];
while(x!=r){
int t=s[x];
s[x]=r;
x=t;
}
return r;
}
void merge(int x,int y){
int r1=find(x),r2=find(y);
if(r1==r2) return ;
s[r1]=r2;
}
#define pii pair<int,int>
map<pii,int> cnt;
int solve(){
int ans=0;
rep(i,0,int(da.size())-1){
int r=i;
while(r<da.size()&&da[r].w==da[i].w) r++;
int cnt1=0,cnt2=0;
rep(j,i,r-1){
if(find(da[j].u)!=find(da[j].v)){
cnt1++;
}
}
rep(j,i,r-1){
if(find(da[j].u)!=find(da[j].v)){
cnt2++;
merge(da[j].u,da[j].v);
}
}
//cerr<<cnt1<<" "<<cnt2<<endl;
ans+=cnt1-cnt2;
cnt.clear();
i=r-1;
}
return ans;
}
int main()
{
#ifndef ONLINE_JUDGE
freopen("in.txt","r",stdin);
freopen("out.txt","w",stdout);
#endif
//clock_t c1 = clock();
//===========================================================
read(n),read(m);
rep(i,1,n) s[i]=i;
rep(i,1,m){
int a,b,c;read(a),read(b),read(c);
//if(a>b) swap(a,b);
da.push_back(Edge(a,b,c));
//que.push(Edge(a,b,c));
}
/*rep(i,0,int(da.size())-1){
cerr<<da[i].u<<" "<<da[i].v<<" "<<da[i].w<<endl;
}
cerr<<"ok"<<endl;*/
sort(da.begin(),da.end(),cmp);
write(solve());
//===========================================================
//std::cerr << "Time:" << clock() - c1 << "ms" << std::endl;
return 0;
}