SMU Spring 2023 Contest Round 1

SMU Spring 2023 Contest Round 1

B - Contest Preparation

思路:特判下m大于n的情况,只有make后才能validate

#include<bits/stdc++.h>
using namespace std;
typedef pair<int,int>PII;
typedef pair<string,int>PSI;
const int N=2e5+5,INF=0x3f3f3f3f,Mod=1e6;

const double eps=1e-6;
typedef long long ll;


ll t,n,m;
int main(){
    ios::sync_with_stdio(0),cin.tie(0),cout.tie(0);
    cin>>t;
    while(t--){
        cin>>n>>m;
        ll s=(2*n+m-1)/m;
        if(m>n&&n)s=2;
        cout<<s<<'\n';
    }
    return 0;
}
View Code

 

D - Difference

思路:

可以把第k大转换为第几小,二分答案;

check时求f(l,r)可以用st表,手写log,复杂度O(1);st表:https://oi-wiki.org/ds/sparse-table/

check求小于等于mid的f(l,r)个数时,(由于f(l,r-1)<f(l,r)>f(l+1,r);对于特定的l,j递增,f(l,j)也是递增的;同理特定的r也是;)枚举l,求出f(l1,r1)小于等于mid的边界r1,接着继续枚举到l2时,由于f是递增的,f(l2,r1)一定小于等于mid,即r2从上一个r1+1开始遍历,可以用双指针,复杂度O(n);

#include<bits/stdc++.h>
using namespace std;
typedef pair<int,int>PII;

typedef pair<string,int>PSI;
const int N=5e5+5,INF=0x3f3f3f3f,Mod=1e9+7;

const double eps=1e-6;
typedef long long ll;
typedef pair<ll,ll>PLL;
ll n,k;
PLL f[N][20];
ll Log[N];

ll P(int l,int r){
    int s=r-l+1;
    ll ma=max(f[l][Log[s]].first,f[r-(1<<Log[s])+1][Log[s]].first);
    ll mi=min(f[l][Log[s]].second,f[r-(1<<Log[s])+1][Log[s]].second);
    return (ma-mi)*1ll*s*1ll;
}

bool check(ll x){
    ll cnt=0;
    int j=1;
    for(int i=1;i<=n;++i){
        if(i>j)j=i;
        while(j<=n&&P(i,j)<=x)j++;
        cnt+=(j-i)*1ll;
    }
    return cnt>=k;
}

int main(){
    ios::sync_with_stdio(0),cin.tie(0),cout.tie(0);
    cin>>n>>k;
    k=n*(n+1)/2-k+1;
    for(int i=1;i<=n;++i)cin>>f[i][0].first,f[i][0].second=f[i][0].first;
    for(int i=2;i<=n;++i)Log[i]=Log[i/2]+1;
    for(int i=1;i<=20;++i)
        for(int j=1;j+(1<<i)-1<=n;++j){
            f[j][i].first=max(f[j][i-1].first,f[j+(1<<(i-1))][i-1].first);
            f[j][i].second=min(f[j][i-1].second,f[j+(1<<(i-1))][i-1].second);
        }
    ll ma=max(f[1][Log[n]].first,f[n-(1<<Log[n])+1][Log[n]].first);
    ll mi=min(f[1][Log[n]].second,f[n-(1<<Log[n])+1][Log[n]].second);
    ll l=0,r=n*(ma-mi)*1ll;
    //cout<<ma<<" "<<mi<<'\n';
    while(l<r){
        ll mid=l+r>>1;
        if(check(mid))r=mid;
        else l=mid+1;
    }
    cout<<l;
    return 0;
}
View Code

 

K - Triangles

思路:对于只有斜率为1这种直线,可直接用x-y映射出位置(同理斜率为-1时可用x+y映射),求三角形个数:有k个点连续的直线形成的个数为 k *(k+1)/ 2;求出所有连续点的个数即可;

#include<bits/stdc++.h>
using namespace std;
typedef pair<int,int>PII;
typedef pair<string,int>PSI;
const int N=2e5+5,INF=0x3f3f3f3f,Mod=1e6;

const double eps=1e-6;
typedef long long ll;


int n;
int a[505][505];
int main(){
    ios::sync_with_stdio(0),cin.tie(0),cout.tie(0);
    cin>>n;
    for(int i=0,x,y;i<n;++i){
        cin>>x>>y;
        a[x][y]=1;
    }
    int b=0;
    for(int i=1;i<=500;++i) {
        for (int j = 0; j + i <= 500; ++j) {
            int x = 1 + j, y = i + j, c = 1;
            if (a[x][y] == 0)continue;//cout<<"*\n";
            while (x + 1 <= 500 && y + 1 <= 500 && a[x+1][y+1]==1) {//cout<<x<<' '<<y<<'\n';
                a[x][y]=0;
                x++, y++;
                c++;
            }//cout<<x<<' '<<y<<'\n';
            a[x][y]=0;
            b += c*(c+1)/2;
        }
    }
    int bb=0;
    for(int i=2;i<=500;++i){
        for(int j=0;j+i<=500;++j){
            int x=i+j,y=1+j,c=1;
            if(a[x][y]==0)continue;//cout<<"*\n";
            while(x+1<=500&&y+1<=500&&a[x+1][y+1]){//cout<<x<<' '<<y<<'\n';
                a[x][y]=0;
                x++,y++;
                c++;
            }
            a[x][y]=0;
            //cout<<x<<' '<<y<<'\n';
            bb+=c*(c+1)/2;
        }
    }
    //cout<<b<<' '<<bb<<'\n';
    cout<<(b+bb)*2;
    return 0;
}
View Code

 

M - XOR Almost Everything

思路:两种方法:

1.对所有数操作一次,每次操作异或的数为本身

2.对相邻每两个数分别进行一次操作,两次操作异或的数为第一个数,得到最后一个数为所有数的异或和,其余数为0;再对最后一个数操作,异或的数为最后一个数

最后所有数都等于所有数的异或和p,在对所有数进行方法一,得到所有数为p^p^p.....(n个),判断n的奇偶即可,偶数一定可以,奇数时所有数的异或和为0则可以;

#include<bits/stdc++.h>
using namespace std;
typedef pair<int,int>PII;
typedef pair<string,int>PSI;
const int N=2e5+5,INF=0x3f3f3f3f,Mod=1e6;

const double eps=1e-6;
typedef long long ll;


int n;

int main(){
    ios::sync_with_stdio(0),cin.tie(0),cout.tie(0);
    cin>>n;
    ll s=0,x;
    for(int i=0;i<n;++i){
        cin>>x;
        s^=x;
    }
    if(s==0&&n%2==1||n%2==0)cout<<"YES";
    else cout<<"NO";
    return 0;
}
View Code

 

posted @ 2023-05-04 10:06  bible_w  阅读(14)  评论(0编辑  收藏  举报