暑假集训日记——7.31(牛客+codeforce)

C. MP3
题解:离散化
15分钟写完代码,发现卡在test 4,到比赛结束都没找出来错误,然后发现自己漏看了一个条件…然后改了一个数字,A了,emmmm,我能说啥呢。
距离1700还有372分——距离暑假结束还有30天

#include<bits/stdc++.h>
#define mp make_pair
using namespace std;

typedef long long ll;
typedef pair<int, int> pii;
typedef pair<ll, int> pli;
typedef pair<ll, ll> pll;
typedef long double ld;

const int N=1e6+10;
const int MAXN=20010;
const int INF=0x3f3f3f3f;
const double eps=0.0000001;
const ll mod=998244353 ;
int n,m,x,y,k,cnt;
int a[N],t[N],b[N],vis[N];

int main()
{
    ios::sync_with_stdio(false); cin.tie(0); cout.tie(0);
    scanf("%d%d",&n,&m);
    int k=8*m/n;
    for(int i=1;i<=n;i++)
    {
        scanf("%d",&a[i]);
        t[i]=a[i];
    }
    if(k>=25)
    {
        printf("0\n");
        return 0;
    }
    else
    {
        cnt=1;
        for(int i=1;i<=k;i++)
            cnt*=2;
        if(cnt>=n)
        {
            printf("0\n");
            return 0;
        }
    }
    sort(t+1,t+n+1);
    x=unique(t+1,t+1+n)-t-1;
    for(int i=1;i<=n;i++)
    b[i]=lower_bound(t+1,t+1+x,a[i])-t;
    for(int i=1;i<=n;i++)
    {
        vis[b[i]]++;
    }
    if(cnt>=x)
    {
        printf("0\n");
        return 0;
    }
    int sum=0,pp=0;
    for(int i=1;i<=cnt;i++)
    {
        sum+=vis[i];
    }
    pp=max(pp,sum);
    for(int i=2;i<=x-cnt+1;i++)
    {
        sum-=vis[i-1];
        sum+=vis[i+cnt-1];
        pp=max(pp,sum);
    }
    printf("%d\n",n-pp);
}

QAQ
题解:后缀和

#include<bits/stdc++.h>
#define mp make_pair
using namespace std;

typedef long long ll;
typedef pair<int, int> pii;
typedef pair<ll, int> pli;
typedef pair<ll, ll> pll;
typedef long double ld;

const int N=1e6+10;
const int MAXN=20010;
const int INF=0x3f3f3f3f;
const double eps=0.0000001;
const ll mod=998244353 ;
int n,m,x,y,k,cnt;
char str[N];
ll a[N],t[N],b[N],vis[N];

int main()
{
    ios::sync_with_stdio(false); cin.tie(0); cout.tie(0);
    scanf("%s",str);
    ll len=strlen(str);
    for(int i=len-1;i>=0;i--)
    {
        if(str[i]=='Q') a[i]=a[i+1]+1;
        else
        a[i]=a[i+1];
    }
    ll ans=0;
    for(int i=0;i<len;i++)
    {
        if(str[i]=='Q')
        for(int j=i+2;j<len;j++)
        {
            if(str[j]=='A')
            {
                ans+=a[j+2];
            }
        }
    }
    printf("%lld\n",ans);
}

Tic-Tac-Toe
题解:暴力

#include<bits/stdc++.h>
#define ll long long
using namespace std;
int mp[10][10];
char s[10];
bool win(){
    if(mp[0][0]+mp[0][1]+mp[0][2]==2) return 1;
    if(mp[1][0]+mp[1][1]+mp[1][2]==2) return 1;
    if(mp[2][0]+mp[2][1]+mp[2][2]==2) return 1;
 
    if(mp[0][0]+mp[1][0]+mp[2][0]==2) return 1;
    if(mp[0][1]+mp[1][1]+mp[2][1]==2) return 1;
    if(mp[0][2]+mp[1][2]+mp[2][2]==2) return 1;
 
    if(mp[0][0]+mp[1][1]+mp[2][2]==2) return 1;
    if(mp[0][2]+mp[1][1]+mp[2][0]==2) return 1;
 
    return 0;
}
bool solve(){
    for(int i=0;i<3;i++){
        for(int j=0;j<3;j++){
            if(mp[i][j]==1){
                mp[i][j]=0;
                if(!win()) return 1;
                mp[i][j]=1;
            }
        }
    }
    return 0;
}
int main(){
    int T;
    cin>>T;
    while(T--){
        for(int i=0;i<3;i++){
            scanf("%s",s);
            for(int j=0;j<3;j++){
                if(s[j]=='#') mp[i][j]=0;
                if(s[j]=='W') mp[i][j]=1;
                if(s[j]=='B') mp[i][j]=-1;
            }
        }
        if(!win()){
            printf("Bob\n");
        }
        else{
            if(solve()) printf("Emmm\n");
            else printf("Alice\n");
        }
    }
    return 0;
}

Buy Fruits
题解:把Ai 理解为需要走的步数,然后商店的布局是一个环就好了
然后证明了偶数有唯一解后,也想不出构造的方法,硬凑吧
在这里插入图片描述

#include<bits/stdc++.h>
using namespace std;
int n,a[110000];
void solve(){
    cin>>n;
    if(n==1) printf("0");
    else if(n==2) printf("1 0");
    else if(n%2) printf("-1");
    else{
        for(int i=0;i<n/2;i++) printf("%d ",n-1-2*i);
        printf("0 ");
        for(int i=n/2+1;i<n-1;i++) printf("%d ",n-2*(i-n/2));
        printf("2");
    }
 
}
int main(){
    solve();
    return 0;
}

小y的序列
题解:注意判断当颜色没有出现时,因为颜色可能被覆盖掉了

#include<cstdio>
#include<iostream>
#include<cstdlib>
#include<cstring>
#include<cassert>
#include<algorithm>
#include<queue>
#include<vector>
#include<ctime>
using namespace std;
typedef long long ll;
const int N = 100000 + 100;
ll read() {
    ll x=0,f=1;char c=getchar();
    while(c<'0'||c>'9') {
        if(c=='-') f=-1;
        c=getchar();
    }
    while(c>='0'&&c<='9') {
        x=x*10+c-'0';
        c=getchar();
    }
    return x*f;
}
int a[N],L[N],R[N];
int main() {
    int n = read(),m = read();

    memset(L,0x3f,sizeof(L));
    for(int i = 1;i <= n;++i) {
        int x = read();
        L[x] = min(L[x],i);

        R[x] = max(R[x],i);
    }
    for(int i = m;i >= 1;--i) {
        if(!R[i]) L[i] = L[i + 1],R[i] = R[i + 1];
    }
 
    for(int i = 1;i <= m;++i) printf("%d %d\n",L[i],R[i]);
    return 0;
}

小y的线段
题解:暴力也不会了
1e7的范围,基本只能O(n)的做了,因为也法优化到O(logn)
如果朴素的想一想就是,因为每个线段到跳回0的位置不同,所以对每个线段求一个跳跃次数然后求和,但复杂度是O(n^2),当然不能考虑。
然后思考一下,这个总个数其实就是每个线段到n的距离加上每个线段跳回0的次数,距离之和很好求,那么就考虑跳回的次数之间有什么关系。
正难则反,因为正向条件不好转移,我们考虑倒着逆推,
先考虑 回到0 的条件可以当作从某一点A 到这个线段的步数大于 ai,所以i<A 的点都会跳到0这一点,然后从n-1->1递推就好了

#include<iostream>
#include<algorithm>
#include<cstdio>
#include<cstdlib>
#include<cstring>
#include<string>
#include<cmath>
#include<queue>
#include<bitset>
#include<set>
#include<stack>
#include<map>
#include<list>
#include<new>
#include<vector>
 
#define MT(a, b) memset(a,b,sizeof(a));
using namespace std;
typedef long long ll;
typedef unsigned long long ull;
const double pai = acos(-1.0);
const double E = 2.718281828459;
//const ll mod = 1000000007;
const int INF = 0x3f3f3f3f;
const int maxn = 1e5 + 5;
 
int a[20000010];
unsigned int SA, SB, SC;
int mod;
 
unsigned int Rand() {
    SA ^= SA << 16;
    SA ^= SA >> 5;
    SA ^= SA << 1;
    unsigned int t = SA;
    SA = SB;
    SB = SC;
    SC ^= t ^ SA;
    return SC;
}
 
int main() {
    ll n;
    cin >> n >> mod >> SA >> SB >> SC;
    for (int i = 1; i <= n; ++i) a[i] = Rand() % mod + 1;
    ll ans = n * (n - 1) / 2;
    int x = a[n];
    for (ll i = n - 1; i >= 1; --i) {
        x--;
        if (x > a[i])   ///取小的值作为限制条件
            x = a[i];
        if (x == 0) {   ///这个位置前面的每个线段都会多跳跃一次
            ans = ans + (i - 1);
            x = a[i];
        }
    }
    cout << ans << endl;
    return 0;
}
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值