A 输出第1 2 4 7...位置的字母即可
#include <bits/stdc++.h>
#define fir first
#define se second
#define ll long long
#define pb push_back
#define mp make_pair
#define ull unsigned long long
#define cl(a,b) memset(a,b,sizeof(a))
#define quickio(a) ios::sync_with_stdio(a)
#define datatest() freopen("data.in","r",stdin)
#define pii pair<int,int>
#define pdd pair<double,double>
using namespace std;
const int maxn=2e5+10;
const int maxm=1e6+10;
const ll INF=1e12;
const ll mod=1e9+8;
const int maxblock=sqrt(1e9)+10;
int n;
char str[maxn];
int main(){
while (~scanf("%d",&n)){
scanf("%s",str+1);
string ans;
int pos=1;
for (int i=1;i<=10;i++){
if (pos>n) break;
ans+=str[pos];
pos+=i;
}
cout<<ans<<endl;
}
return 0;
}
B 只有在删掉最小/最大的那个值才会有可能更改答案 排序后只要在最小值/最大值的地方讨论即可
#include <bits/stdc++.h>
#define fir first
#define se second
#define ll long long
#define pb push_back
#define mp make_pair
#define ull unsigned long long
#define cl(a,b) memset(a,b,sizeof(a))
#define quickio(a) ios::sync_with_stdio(a)
#define datatest() freopen("data.in","r",stdin)
#define pii pair<int,int>
#define pdd pair<double,double>
using namespace std;
const int maxn=2e5+10;
const int maxm=1e6+10;
const ll INF=1e12;
const ll mod=1e9+8;
const int maxblock=sqrt(1e9)+10;
int n,a[maxn];
int main(){
while (~scanf("%d",&n)){
for (int i=1;i<=n;i++) scanf("%d",&a[i]);
sort(a+1,a+n+1);
int res=a[n]-a[1];
res=min(res,a[n]-a[2]);
res=min(res,a[n-1]-a[1]);
printf("%d\n",res);
}
return 0;
}
C 枚举n的为1的二进制位,如果这时候数量不够 就把这个位*2补到下一位 直到满足条件或者所有数都拆成1
#include <bits/stdc++.h>
#define fir first
#define se second
#define ll long long
#define pb push_back
#define mp make_pair
#define ull unsigned long long
#define cl(a,b) memset(a,b,sizeof(a))
#define quickio(a) ios::sync_with_stdio(a)
#define datatest() freopen("data.in","r",stdin)
#define pii pair<int,int>
#define pdd pair<double,double>
using namespace std;
const int maxn=2e5+10;
const int maxm=1e6+10;
const ll INF=1e12;
const ll mod=1e9+8;
const int maxblock=sqrt(1e9)+10;
map<int,int> ma;
int n,k;
int num=0;
int main(){
scanf("%d %d",&n,&k);
for (int i=0;i<30;i++){
if (n&(1<<i)){
ma[(1<<i)]++;
num++;
}
}
for (int i=29;i>0;i--){
if (num>k) break;
if (ma.count(1<<i)==0) continue;
int temp=ma[1<<i];
int dif=k-num;
if (temp>dif){
ma[1<<(i-1)]+=2*dif;
ma[1<<i]-=dif;
num+=dif;
}
else{
ma[1<<(i-1)]+=2*temp;
ma[1<<i]=0;
num+=temp;
}
}
if (num!=k){
printf("NO\n");
}
else{
printf("YES\n");
for (int i=29;i>=0;i--){
if (ma[1<<i]){
for (int j=0;j<ma[1<<i];j++){
printf("%d ",(1<<i));
}
}
}
printf("\n");
}
return 0;
}
D 枚举第一个的情况 之后check一遍即可
#include <bits/stdc++.h>
#define fir first
#define se second
#define ll long long
#define pb push_back
#define mp make_pair
#define ull unsigned long long
#define cl(a,b) memset(a,b,sizeof(a))
#define quickio(a) ios::sync_with_stdio(a)
#define datatest() freopen("data.in","r",stdin)
#define pii pair<int,int>
#define pdd pair<double,double>
using namespace std;
const int maxn=2e5+10;
const int maxm=1e6+10;
const ll INF=1e12;
const ll mod=1e9+8;
const int maxblock=sqrt(1e9)+10;
int n;
int a[maxn][2];
vector<int> res;
int solve(int p1,int p2){
res.clear();
res.pb(1);
res.pb(a[1][p1]);
res.pb(a[1][p2]);
for (int i=1;i<=n-2;i++){
/* cout<<"i="<<i<<endl;
for (int i=0;i<res.size();i++){
cout<<res[i]<<" ";
}*/
cout<<endl;
int pos=res[i];
int pos1=res[i+1];
if (a[pos][1]!=pos1&&a[pos][0]!=pos1) return 0;
if (a[pos][1]==pos1){
res.pb(a[pos][0]);
}
else{
res.pb(a[pos][1]);
}
}
int aa=res[0];
int bb=res[1];
int pos=res[n-1];
if (aa==a[pos][0]&&bb==a[pos][1]) return 1;
if (aa==a[pos][1]&&bb==a[pos][0]) return 1;
return 0;
}
int main(){
while (scanf("%d",&n)!=EOF){
for (int i=1;i<=n;i++){
scanf("%d %d",&a[i][0],&a[i][1]);
}
if (solve(0,1)){
for (int i=0;i<res.size()-1;i++){
printf("%d ",res[i]);
}
printf("\n");
continue;
}
if (solve(1,0)){
for (int i=0;i<res.size()-1;i++){
printf("%d ",res[i]);
}
printf("\n");
continue;
}
printf("NO\n");
}
return 0;
}
E 预处理出括号序列的前缀和之后
对于一个位置从)改成( 相当于从他开始之后的所有位置+2
所以只要判断1~i-1的最小值是否大于等于0且i到n的最小值是否大于等于-2
用线段树维护即可
(改成)是类似的
#include <bits/stdc++.h>
#define fir first
#define se second
#define ll long long
#define pb push_back
#define mp make_pair
#define ull unsigned long long
#define cl(a,b) memset(a,b,sizeof(a))
#define quickio(a) ios::sync_with_stdio(a)
#define datatest() freopen("data.in","r",stdin)
#define pii pair<int,int>
#define pdd pair<double,double>
using namespace std;
const int maxn=1e6+10;
const int maxm=1e6+10;
const ll INF=1e12;
const ll mod=1e9+8;
const int maxblock=sqrt(1e9)+10;
char str[maxn];
int n;
int tree[maxn<<2];
int sum[maxn];
void pushup(int rt){
tree[rt]=min(tree[rt<<1],tree[rt<<1|1]);
}
void build(int rt,int l,int r){
if (l==r){
tree[rt]=sum[l];
return ;
}
int mid=(l+r)>>1;
build(rt<<1,l,mid);
build(rt<<1|1,mid+1,r);
pushup(rt);
}
int query(int rt,int l,int r,int L,int R){
if (L>R){
return 1;
}
int Min=1e8;
if (l>=L&&r<=R) return tree[rt];
int mid=(l+r)>>1;
if (L<=mid){
Min=min(Min,query(rt<<1,l,mid,L,R));
}
if (R>mid){
Min=min(Min,query(rt<<1|1,mid+1,r,L,R));
}
return Min;
}
int main(){
while (~scanf("%d",&n)){
scanf("%s",str+1);
sum[0]=0;
for (int i=1;i<=n;i++){
if (str[i]=='(')
sum[i]=sum[i-1]+1;
else sum[i]=sum[i-1]-1;
}
build(1,1,n);
int ans=0;
for (int i=1;i<=n;i++){
if (str[i]=='('){
if (sum[n]!=2) continue;
int Min=query(1,1,n,i,n);
int Min1=query(1,1,n,1,i-1);
if (Min>=2&&Min1>=0){
//cout<<"i="<<i<<endl;
ans++;
}
}
if (str[i]==')'){
if (sum[n]!=-2) continue;
int Min=query(1,1,n,i,n);
int Min1=query(1,1,n,1,i-1);
if (Min>=-2&&Min1>=0){
// cout<<"i="<<i<<endl;
ans++;
}
}
}
printf("%d\n",ans);
}
return 0;
}
F 如果没有特殊边 显然是把a最小的点跟其他点连成一个菊花图
只要把这n-1条边跟m条边一起跑一个mst出来就可以了
#include <bits/stdc++.h>
#define fir first
#define se second
#define ll long long
#define pb push_back
#define mp make_pair
#define ull unsigned long long
#define cl(a,b) memset(a,b,sizeof(a))
#define quickio(a) ios::sync_with_stdio(a)
#define datatest() freopen("data.in","r",stdin)
#define pii pair<int,int>
#define pdd pair<double,double>
using namespace std;
const int maxn=2e5+10;
const int maxm=1e6+10;
const ll INF=1e12;
const ll mod=1e9+8;
const int maxblock=sqrt(1e9)+10;
struct Edge{
int u,v;
ll w;
};
vector<Edge> V;
int n,m;
ll a[maxn];
int cmp(Edge a,Edge b){
return a.w<b.w;
}
int fa[maxn];
int tfind(int x){
if (fa[x]==x) return x;
else return fa[x]=tfind(fa[x]);
}
ll solve(){
sort(V.begin(),V.end(),cmp);
ll tot=0;
ll num=0;
for(int i=1;i<=n;i++) fa[i]=i;
for (int i=0;i<V.size();i++){
if (num==n-1) break;
int u=V[i].u;
int v=V[i].v;
ll w=V[i].w;
int a=tfind(u);
int b=tfind(v);
if (a==b) continue;
fa[a]=b;
tot+=w;
num++;
}
return tot;
}
int main(){
scanf("%d %d",&n,&m);
for (int i=1;i<=n;i++){
scanf("%lld",&a[i]);
}
for (int i=1;i<=m;i++){
int u,v;
ll w;
scanf("%d %d %lld",&u,&v,&w);
V.pb(Edge{u,v,w});
}
int rt=-1;
ll Min=INF;
for (int i=1;i<=n;i++){
Min=min(Min,a[i]);
}
for (int i=1;i<=n;i++){
if (a[i]==Min){
rt=i;
break;
}
}
for (int i=1;i<=n;i++){
if (i==rt) continue;
V.pb(Edge{i,rt,a[i]+a[rt]});
}
ll res=solve();
printf("%lld\n",res);
return 0;
}