===20180619SHU暑期集训个人赛(1)===

找规律 注意位运算 多半是对位的找规律

Select Code
#include <bits/stdc++.h>
using namespace std;
#define clr(a, x) memset(a, x, sizeof(a))
#define mp(x, y) make_pair(x, y)
#define pb(x) push_back(x)
#define X first
#define Y second
#define fastin                    \
    ios_base::sync_with_stdio(0); \
    cin.tie(0);
typedef long long LL;
typedef long double Ld;
typedef pair<int, int> PII;
typedef vector<int> VI;
const int INF = 0x3f3f3f3f;
const int mod = 1e9 + 7;
const double eps = 1e-6;
LL a[100010];
LL b[100010];
int n;
LL func(LL x){
    return x*(x+1)/2;
}
LL coun(){
    LL num=0;
    LL ans=0;
    for(int i=0;i<n;i++){
        if(num>0&&b[i]==0) { ans+=func(num);num=0; }
        if(b[i]==1) num++;
    }
    ans+=func(num);
    return ans;
}

int main()
{
    int t;scanf("%d",&t);
    while(t--){

        scanf("%d",&n);LL _max=0;

        for(int i=0;i<n;i++){
            scanf("%lld",&a[i]);_max=max(_max,a[i]);
        }

        int wei=log2(_max);
        wei+=2;
        LL ans=0;
        LL basic=1;
        for(int i=0;i<wei;i++,basic<<=1){
            for(int j=0;j<n;j++){
                b[j]= a[j]&1;
                a[j]>>=1;
            }
            ans+=basic*coun();
        }
        printf("%lld\n",ans);
    }

    return 0;
}
/*
2
3
7 11 9
4
11 9 6 11

*/



    简单题 我都记不清是什么题了 多半是尝试 打印答案
//想起华师的第二道题 妈的
 
 


#include <bits/stdc++.h>
using namespace std;
#define clr(a, x) memset(a, x, sizeof(a))
#define mp(x, y) make_pair(x, y)
#define pb(x) push_back(x)
#define X first
#define Y second
#define fastin                    \
    ios_base::sync_with_stdio(0); \
    cin.tie(0);
typedef long long LL;
typedef long double Ld;
typedef pair<int, int> PII;
typedef vector<int> VI;
const int INF = 0x3f3f3f3f;
const int mod = 1e9 + 7;
const double eps = 1e-6;
LL a[1010];
int n;
void print_ans(int x,LL val,LL m)
{
    for(int i=x+1;i<n;i++){
        a[i]=(a[i-1]+1)%m;
    }
    for(int i=x-1;i>=0;i--){
        a[i]=(a[i+1]-1+m)%m;
    }
    for(int i=0;i<n-1;i++)
    cout<<a[i]<<" ";
    cout<<a[n-1]<<endl;

}


int main()
{
    fastin
    int t;cin>>t;
    for(int i=0;i<t;i++){
        LL m;cin>>n>>m;
        for(int i=0;i<n;i++) cin>>a[i];

        for(int i=0;i<n;i++) if(a[i]!=-1) {print_ans(i,a[i],m);break;}
    }


    return 0;
}
/*
4
5 10
1 2 3 4 5
4 10
7 -1 9 -1
6 7
5 -1 -1 1 2 3
6 10
5 -1 7 -1 9 0

*/
二分 没什么特殊的 没接触过罢了

lower_bound() >=

upper_bound() >


Select Code
#include <bits/stdc++.h>
using namespace std;
#define clr(a, x) memset(a, x, sizeof(a))
#define mp(x, y) make_pair(x, y)
#define pb(x) push_back(x)
#define X first
#define Y second
#define fastin                    \
    ios_base::sync_with_stdio(0); \
    cin.tie(0);

typedef long long LL;
typedef long double Ld;
typedef pair<int, int> PII;
typedef vector<int> VI;
const int INF = 0x3f3f3f3f;
const int mod = 1e9 + 7;
const double eps = 1e-6;
struct  node{
    int no;
    int val;
    int ans;
};
int n;
node a[200100];
bool cmp1(node a,node b){
    return a.val<b.val;
}
bool cmp2(node a,node b){
    return a.no<b.no;
}
int findkey(int val,int pos){
    int l=0,r=n-1;
    int mid;
    while(l<=r){
        mid=(l+r)/2;
        if(a[mid].val>val) r=mid-1;
        else l=mid+1;
    }
    if(r==pos) r--;
    if(r<0) return a[(pos+1)%n].val;
    return a[r].val;
}
int main()
{
    fastin
    int t;cin>>t;
    while(t--){
        cin>>n;
        for(int i=0;i<n;i++) {cin>>a[i].val;a[i].no=i;}

        sort(a,a+n,cmp1);

        for(int i=0;i<n;i++){
            int ans1;
            if(i==n-1) ans1=(a[n-2].val+a[n-1].val)%mod;
            else ans1=(a[n-1].val+a[i].val)%mod;

            int tmp=findkey(mod-a[i].val-1,i);
            int ans2=(a[i].val+tmp)%mod;
            a[i].ans=max(ans1,ans2);
        }

        sort(a,a+n,cmp2);
        for(int i=0;i<n-1;i++) cout<<a[i].ans<<" ";
        cout<<a[n-1].ans<<endl;
    }
    return 0;
}
/*
3
3
1 2 3
2
1000000000 1000000000
3
500000007 500000002 500000003

*/
预处理+查询

注意l-r可以处理为 1~r -1~l-1 简单好多


Select Code
#include <bits/stdc++.h>
using namespace std;
#define clr(a, x) memset(a, x, sizeof(a))
#define mp(x, y) make_pair(x, y)
#define pb(x) push_back(x)
#define X first
#define Y second
#define fastin                    \
    ios_base::sync_with_stdio(0); \
    cin.tie(0);

typedef long long LL;
typedef long double Ld;
typedef pair<int, int> PII;
typedef vector<int> VI;
const int INF = 0x3f3f3f3f;
const int mod = 1e9 + 7;
const double eps = 1e-6;
LL a[10010][26];
char tmp;
LL func(LL s,LL e){
    if(s==0) return a[e][tmp-'a'];
    return a[e][tmp-'a']-a[s-1][tmp-'a'];
}


int main()
{
    int t;scanf("%d",&t);
    while(t--){
        int n,m;
        scanf("%d %d",&n,&m);
        memset(a,0,sizeof a);
        string s;cin>>s;

        a[0][s[0]-'a']++;
        for(int i=1;i<n;i++){
            int num=s[i]-'a';
            a[i][num]++;
            for(int j=0;j<26;j++) a[i][j]+=a[i-1][j];
        }

        for(int i=0;i<m;i++){
            LL ans=0;
            LL l,r;scanf("%lld %lld %c",&l,&r,&tmp);
            l-=1;r-=1;
            if(r-l<n){
                r%=n,l%=n;
               if(r>=l) ans+=func(l,r);
                else{
                    ans+=func(l,n-1);
                    ans+=func(0,r);
                }
            }
            else{
                LL len1=r%n,len2=n-l%n;
                ans+=func(l%n,n-1);
                ans+=func(0,r%n);
                ans+=(r-l-len1-len2) / n * a[n-1][tmp-'a'];
            }
            printf("%lld\n",ans);
        }

    }
}
/*
1
8 5
abcabdca
1 1 c
1 15 b
4 9 a
5 25 d
2 7 c

*/
折半查找 第一次做 还可以


Select Code
#include <bits/stdc++.h>
using namespace std;
#define clr(a, x) memset(a, x, sizeof(a))
#define mp(x, y) make_pair(x, y)
#define pb(x) push_back(x)
#define X first
#define Y second
#define fastin                    \
    ios_base::sync_with_stdio(0); \
    cin.tie(0);
typedef long long LL;
typedef long double Ld;
typedef pair<int, int> PII;
typedef vector<int> VI;
const int INF = 0x3f3f3f3f;
const LL mod = 1e9 + 7;
const double eps = 1e-6;
LL a[500][7];
map<LL,int> c;
int n;LL m;
LL res=0;
long long quickmod(long long a,long long b,long long m)
{
    long long ans = 1;
    while(b){
        if(b&1){
            ans = (ans*a)%m;b--;
        }
        b/=2;
        a = a*a%m;
    }
    return ans;
}


void dfs1(int cur,int e,LL ans){
    if(cur==e){
        ++c[ans];
        return ;
    }
    for(int i=0;i<6;i++) {
        dfs1(cur+1,e,(ans*a[cur][i])%mod);
    }
}
void dfs2(int cur,int e,LL ans){
    if(cur==e){
        res+=c[(m*quickmod(ans,mod-2,mod))%mod];
        return ;
    }
    for(int i=0;i<6;i++) {
        dfs2(cur+1,e,(ans*a[cur][i])%mod); //SDUSHADJKASDNJKASDHJK
    }
}


void init(){
    res=0;
    c.clear();
}

int main()
{
    int t;scanf("%d",&t);
    while(t--){
        scanf("%d %lld",&n,&m);
        init();
        for(int i=0;i<n;i++)
            for(int j=0;j<6;j++)
               scanf("%lld",&a[i][j]);
        int mid=n/2;
        dfs1(0,mid,LL(1));
        dfs2(mid,n,LL(1));
        cout<<res<<endl;
    }
    return 0;
}

1.hash

2.暴力枚举回文子串数量

3.st处理区间问题




Select Code
#include <bits/stdc++.h>
using namespace std;
#define clr(a, x) memset(a, x, sizeof(a))
#define mp(x, y) make_pair(x, y)
#define pb(x) push_back(x)
#define X first
#define Y second
#define fastin                    \
    ios_base::sync_with_stdio(0); \
    cin.tie(0);
typedef long long LL;
typedef long double Ld;
typedef pair<int, int> PII;
typedef vector<int> VI;
const int INF = 0x3f3f3f3f;
const int mod = 1e9 + 7;
int func(char s[])
{
    LL ans=0;
    int n=strlen(s);
    for(int i=0; i<n; i++)
    {
        for(int len=1; len<n; len++)
        {
            if(i-len<0||i+len>n) break;
            if(s[i-len]==s[i+len])
                ans++;
            else break;
        }
    }

    for(int i=0; i<n-1; i++)
        if(s[i+1]==s[i])
        {
            ans++;
            for(int len=1; len<n; i++)
            {
                if(i-len<0||i+len>n) break;
                if(s[i-len]==s[i+len+1]) ans++;
                else break;
            }
        }

    return ans;
}
int c[40][40];
int func1(string s)
{
    int len=s.size();
    int sum=0;
    memset(c,0,sizeof c);
    for(int i=len-1; i>=0; i--)
    {
        c[i][i]=true;
        sum++;
        for(int j=i+1; j<len; j++)
        {
            if(s[i]==s[j])
            {
                if(i+1==j||c[i+1][j-1])
                {
                    c[i][j]=true;
                    sum++;
                }
            }
            else c[i][j]=false;
        }
    }
    return sum;
}
LL Hash(string s)
{
    LL ans=0;
    int len=s.size();
    for(int i=0; i<len; i++)
    {
        ans=ans*31+s[i]-'a'+1;
    }
    return ans;
}

struct node
{
    int no;
    int val;
    node(int n=0,int v=0)
    {
        no=n;
        val=v;
    }
    bool operator < (const node& a) const
    {
        if(val==a.val) return no>a.no;
        return val<a.val;
    }
};



char s[40];
int n;
node dp[10100][40];

void st()
{
    for(int j=1;(1<<j)<=n;j++)
        for(int i=1;i+(1<<j)-1<=n;i++)
            dp[i][j]=max(dp[i][j-1],dp[i+(1<<(j-1))][j-1]);
}

node RMQ(int l,int r){
    int k=log2(r-l+1);
    return max(dp[l][k],dp[r-(1<<k)+1][k]);
}

int main()
{
    int t;
    scanf("%d",&t);
    while(t--)
    {
        map<LL,int> mp;
        int q;
        scanf("%d%d",&n,&q);

        for(int i=1; i<=n; i++)
        {
            scanf("%s",s);
            int num=func1(s);
            LL hs=Hash(s);
            mp[hs]=i;
            dp[i][0]=node(i,num);
        }
        st();
        for(int i=1; i<=q; i++)
        {
            char tmp1[40],tmp2[40];
            scanf("%s",tmp1);
            scanf("%s",tmp2);

            LL hs1=Hash(tmp1),hs2=Hash(tmp2);
            int n1=mp[hs1],n2=mp[hs2];

            if(n1>n2) swap(n1,n2);
            printf("%d\n",RMQ(n1,n2).no);
        }
    }
    return 0;
}
int main1()
{

    cout<<Hash("aaaa")<<endl;
    cout<<Hash("aaaaa")<<endl;
}



/*
3
5 5
aaaaaaaaaaaaaaaaaaaaaaaa
bbbbbbbbbbbbbbbbbbbbbbbb
cccaaaaccccaa
aaaaaaaaaaaaa
acccccc
acccccc aaaaaaaaaaaaa
bbbbbbbbbbbbbbbbbbbbbbbb aaaaaaaaaaaaaaaaaaaaaaaa
aaaaaaaaaaaaa cccaaaaccccaa
aaaaaaaaaaaaa aaaaaaaaaaaaaaaaaaaaaaaa
acccccc aaaaaaaaaaaaa

*/
前缀 后缀 签到题



Select Code
#include <bits/stdc++.h>
using namespace std;
#define clr(a, x) memset(a, x, sizeof(a))
#define mp(x, y) make_pair(x, y)
#define pb(x) push_back(x)
#define X first
#define Y second
#define fastin                    \
    ios_base::sync_with_stdio(0); \
    cin.tie(0);
typedef long long LL;
typedef long double Ld;
typedef pair<int, int> PII;
typedef vector<int> VI;
const int INF = 0x3f3f3f3f;
const int mod = 1e9 + 7;
const double eps = 1e-6;
int a[1000100];
int maxtou[1000100];
int minwei[1000100];
int main()
{

    int t;scanf("%d",&t);
    while(t--){
        int n; scanf("%d",&n);
        for(int i=0;i<n;i++){
            scanf("%d",&a[i]);
            if(i==0) maxtou[0]=a[0];
            else maxtou[i]=max(maxtou[i-1],a[i]);
        }
        minwei[n-1]=a[n-1];
        for(int i=n-2;i>=0;i--){
            minwei[i]=min(minwei[i+1],a[i]);
        }

        int ans=0;

        for(int i=1;i<n-1;i++){
            if(a[i]<=minwei[i+1]&&a[i]>=maxtou[i-1]) ans++;
            //cout<<a[i].index<<" ";
        }
        printf("%d\n",ans);
    }


    return 0;
}
/*
4
10
1 2 1 1 1 1 1 1 1 1
5
3 3 4 5 3

*/
签到题
注意角上的 唯一的坑点了吧

Select Code
#include <bits/stdc++.h>
using namespace std;
#define clr(a, x) memset(a, x, sizeof(a))
#define mp(x, y) make_pair(x, y)
#define pb(x) push_back(x)
#define X first
#define Y second
#define fastin                    \
    ios_base::sync_with_stdio(0); \
    cin.tie(0);

typedef long long LL;
typedef long double Ld;
typedef pair<int, int> PII;
typedef vector<int> VI;
const int INF = 0x3f3f3f3f;
const int mod = 1e9 + 7;
const double eps = 1e-6;
char a[60][60];
int main()
{
    fastin
    int t;cin>>t;
    while(t--){
        int n,m;cin>>n>>m;
        int num=0;
        for(int i=0;i<n;i++)
            for(int j=0;j<m;j++){
                cin>>a[i][j];
                if(a[i][j]=='1') num++;
            }           
            
        if( num<(2*n+2*m-4) ) {cout<<"-1"<<endl;continue;}
        int ans=0;
        
        for(int j=0;j<m;j++){
            if(a[0][j]=='0') ans++;
            if(a[n-1][j]=='0') ans++;
        }
        for(int i=0;i<n;i++){
            if(a[i][0]=='0') ans++;
            if(a[i][m-1]=='0') ans++;
        }
        if(a[0][0]=='0') ans--;
        if(a[n-1][0]=='0') ans--;
        if(a[0][m-1]=='0') ans--;
        if(a[n-1][m-1]=='0') ans--;
        cout<<ans<<endl;


    }
    return 0;
}
dp 
注意下一个元素是要特殊处理 不然会超时

一步步覆盖 从头 

想想从尾部会怎么样?



Select Code
#include <bits/stdc++.h>
using namespace std;
typedef long long LL;
const int INF = 0x3f3f3f3f;
const int mod = 1e9 + 7;
int a[200110];
int pos[200110];
int dp[200110];
int n;

int main(){
    int t;scanf("%d",&t);
    while(t--){
        int n;scanf("%d",&n);
        dp[0]=-1;
        memset(pos,0,sizeof pos);
        for(int i=1;i<=n;i++){
            int val;
            scanf("%d",&val);
            dp[i]=dp[i-1]+1;
            if(pos[val]!=0)
            dp[i]= min ( dp[i] , dp[ pos[val] ]+1);
            pos[val] = i ;
        }
        printf("%d\n",dp[n]);
    }

}
公式 或者 递推

数学问题


Select Code
#include<bits/stdc++.h>
using namespace std;
typedef long long LL;
const int mod = 1e9+7;
int main()
{
    int t;
    scanf("%d",&t);
    while(t--){
        int n;scanf("%d",&n);
        LL ans=1,tmp;
        while(n--) {scanf("%lld",&tmp); ans=(ans*(tmp+1))%mod;}
        printf("%lld\n",(ans+mod-1)%mod);
    }
    return 0;
}
Select Code
#include <bits/stdc++.h>
using namespace std;
typedef long long LL;
const int INF = 0x3f3f3f3f;
const int mod = 1e9 + 7;

int P[12];
void pre(){
    P[0]=1;
    for(int i=1;i<=11;i++)
       P[i]=i*P[i-1];
}

int main()
{
    pre();
    int t;cin>>t;
    while(t--)
    {
        int n;int l[26];
        memset(l,0,sizeof l);
        cin>>n;
        for(int i=0;i<n;i++)
        {
            char tmp;cin>>tmp;
            l[tmp-'a']++;
        }
        int num=0;
        for(int i=0;i<26;i++) if(l[i]&1) num++;

        if(num>=2){ cout<<0<<endl;continue;}
        int len=0;
        for(int i=0;i<26;i++) {l[i]/=2;len+=l[i];}
        int ans=P[len];
        for(int i=0;i<26;i++) {ans/=P[l[i]];}
        cout<<ans<<endl;
    }



    return 0;
}

二分答案 之后容斥验证


#include <bits/stdc++.h>
using namespace std;
#define clr(a, x) memset(a, x, sizeof(a))
#define mp(x, y) make_pair(x, y)
#define pb(x) push_back(x)
#define X first
#define Y second
#define fastin                    \
    ios_base::sync_with_stdio(0); \
    cin.tie(0);
typedef  long long LL;
typedef  long long ll;

typedef pair<int, int> PII;
typedef vector<int> VI;
const int INF = 0x3f3f3f3f;
const int mod = 1e9 + 7;
const double eps = 1e-6;
void show()
{
    cout<<"ok"<<endl;
}
vector<LL> vec;
LL cnum(LL r) //求1-r中与 k(不)互质 的元素的个数
{
    LL ans=0;
    int wei=vec.size();
    for(LL i=1; i<(1LL<<wei); i++)
    {
        int bits=0,multi=1;
        for(LL j=0; j<wei; j++)
        {
            if(i&(1LL<<j))
            {
                bits++;
                multi*=vec[j];
            }
        }
        LL cur=r/multi;
        if(bits&1) ans+=cur;
        else       ans-=cur;
    }
    //return ans; //返回与其不互质的元素个数
    return r-ans;//返回与其互质的元素个数
}

int main()
{
    int t;
    scanf("%d",&t);
    while(t--)
    {
        LL l,no, p;
        scanf("%lld%lld%lld",&l,&p,&no);
        vec.clear();
        LL ans=0;
        for(LL i=2; i*i<=p; i++)
        {
            if(p%i==0) vec.push_back(i);
            while(p%i==0) p/=i;
        }
        if(p>1) vec.push_back(p);
        LL r=1e12;
        LL tmp=no+cnum(l);
        while(l<=r)
        {
            LL mid=l+(r-l)/2;
            if(cnum(mid)>=tmp)
            {
                ans=mid;
                r=mid-1;
            }
            else l=mid+1;
        }
        printf("%lld\n",ans);
    }


    return 0;
}

CodeForces - 936B

N - Sleepy Game

三种简单图论知识的集合题

1.有向图 dfs判环

vis[] 标记 三种标记 0代表未访问 1代表正在访问这个分支 2代表访问完成某一分支

什么时候会形成环?

这个点的分支在访问的时候又回到了自己这个点

蔡老师强啊

一般我会写

bool huan(int u)
{    bool flag=false;
    c[u]=1;
    for(auto v:G[u])
    {
        if(c[v]==1) return true;        else if(c[v]==0){            if(huan(v)) flag=true;
        }
    }
    c[u]=2;
    return flag;
}
又丑又长

bool huan(int u)
{
    c[u]=1;
    for(auto v:G[u])
    {
        if(c[v]==1||c[v]==0&&huan(v)) return true;
    }
    c[u]=2;
    return false;
}
对判环理解很深刻(&&与||优先级 不要怕 大胆写啊)

2.拆点

一张图拆成两张图 偶数路径 奇数路径

偶-奇-偶-。。。。。

奇-偶-奇。。。

一个点可能既可以在 两种情况下 都被访问 用vis[MAXN][2]全记录下来

3.打印路径

记录每个点在奇偶路径下的父亲 回溯输出

//一开始暴力从始点枚举。。RE了多半递归炸了


#include <bits/stdc++.h>
using namespace std;
typedef long long LL;
const int INF = 0x3f3f3f3f;
const int mod = 1e9 + 7;
const int MAXN = 200100;
vector<int> G[MAXN<<1];
int n,m;
int vis[MAXN][2];//1--到。。。可以为奇数路径
int fa[MAXN][2];
//0--到。。。可以为偶数路径
void dfs(int s,int flag)   //处理出s点的可走路径奇偶
{
    vis[s][flag]=1;
    for(auto v:G[s])
    {
        if(!vis[v][1-flag])
        {
            fa[v][1-flag]=s;
            dfs(v,1-flag);
        }
    }
}
void print_ans(int u,int flag)
{
    if(u==0)
    {
        return ;
    }
    //cout<<u<<" "<<flag<<endl;
    //cout<<fa[u][flag]<<endl;
    print_ans(fa[u][flag],1-flag);
    cout<<u<<" ";
}
void show()
{
    cout<<endl;
    cout<<fa[5][1]<<endl;
    cout<<endl;
    for(int i=1; i<=n; i++)
    {
        for(int j=0; j<2; j++)
            cout<<fa[i][j]<<" ";
        cout<<endl;
    }

}

int c[MAXN];
bool huan(int u)
{
    c[u]=1;
    for(auto v:G[u])
    {
        if(c[v]==1||c[v]==0&&huan(v)) return true;
    }
    c[u]=2;
    return false;
}
int main()
{
    cin>>n>>m;

    memset(vis,0,sizeof vis);
    for(int i=1; i<=n; i++)
    {
        int num;
        cin>>num;
        for(int j=0; j<num; j++)
        {
            int to;
            cin>>to;
            G[i].push_back(to);
        }
    }
    int s;
    cin>>s;
    memset(fa,0,sizeof fa);

    dfs(s,0);
    for(int i=1; i<=n; i++)
        if(G[i].empty()&&vis[i][1])
        {
            cout<<"Win"<<endl;
            print_ans(i,1);
            return 0;
        }

    memset(c,0,sizeof c);
    if(huan(s)) puts("Draw");
    else puts("Lose");
    return 0;
}
 

  • 0
    点赞
  • 2
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值