北邮还是新生吗训练赛12

时间限制 1000 ms  内存限制 65536 KB

题目描述

Study sister plays the game coc everyday. Now she wants to upgrade her wizard in laboratory,but she doesn't know the spell. After research, she finds out that the spells are made by repeat the keyword M times. She checks top players' daily log and get one of their upgrade log.
Now she wants to know how many possible spells are in the log.

 

输入格式

There are several test cases. For each case, the first line consist of two integer M, L, (M*L <= 1e5) means the repeat time and the lenth of the keyword. Next line contains a string means the log. The string is made by lowercase letter.

update: |s| <=1e5

输出格式

For each test case, print one line, the number of the possible spells.

 

输入样例

3 3
abcabcabcabc

输出样例

4

hint:
The four possible spells are:
abcabcabc
bcabcabca
cabcabcab
abcabcabc
问题:题意理解错误,误认为l不确定

思路: 水hash

#include <cstdio>
#include <cstring>
#include <assert.h>
using namespace std;
int m,l,len;
typedef unsigned long long LL;
const int maxlen=100001;
const int prime =31;
LL dp[maxlen];
LL base[maxlen];
char buff[maxlen];
void calc(){
    len=strlen(buff);
    dp[0]=buff[0]-'a';
    base[0]=1;
    for(int i=1;i<len;i++){
        dp[i]=dp[i-1]*prime+buff[i]-'a';
        base[i]=base[i-1]*prime;
    }
}
LL gethash(int s,int e){
    LL ans;
    if(s)ans=dp[e]-dp[s-1]*base[e-s+1];
    else ans=dp[e];
    return ans;
}
int main(){
    while(scanf("%d%d",&m,&l)==2){
        scanf("%s",buff);
        int ans=0;
        assert(l>0);
        LL key,fkey,num;
        calc();
        for(int i=0;i<l;i++){//mod
                key=fkey=gethash(i,l-1+i);
                num=1;
            for(int j=1;j*l+i<len;j++){
                key=gethash(j*l+i,j*l+l-1+i);
                if(key==fkey)num++;
                while(num>=m){
                    num--;
                    ans++;
                }
                fkey=key;
            }
        }
        printf("%d\n",ans);
    }
    return 0;
}

时间限制 1000 ms  内存限制 65536 KB

题目描述

    Your clan has been subjected to the harassment of the goblins. Your leader decided to fight back for peace. But the story is more complex than your imagination, reckoning with the numerous resources wasted in the war, the leader assigned you as the envoy to win the dignity.
    Now you have arrived there, you find the goblins love math very much. They only appreciate the guys with high intellegence, so they give you a math problem, if you can solve it in 1s, they will appreciate you and protect your clan as a gift. For peace, just  fighting!
    They give you a lot of pairs of numbers, denoted by K,N. for every input, you should tell them the sum of k^gcd(i,n), for i = 1~n.
    For the answer is so large, you can give them the answer mod 23333.

 

输入格式

Given T, the number of cases. Then, for next T lines, there are two numbers K,N.(1 <= k <= 10^4, 1 <= n <= 10^8)

 

输出格式

For every case, print one line, containing the answer mod 23333.

 

输入样例

3
3 4
2 6
100 50000000

输出样例

96
84
3014
问题:没有注意到可能分解出大于平方根的质因子

#include <cstdio>
#include <cstring>
#include <assert.h>
using namespace std;
int heap[32];
int times,n,k;
const int mod =23333;
bool notp[10002];
int pheap[10002];
int plen;
long long ans;
long long sum;
long long qpow(int ind){
    if(ind==0)return 1;
    long long a=qpow(ind/2);
    a=a*a%mod;
    if(ind&1)a=a*k%mod;
    return a;
}
void getprime(){
    notp[0]=notp[1]=true;
    pheap[plen++]=2;
    for(int i=3;i<10002;i+=2){
        if(!notp[i]){
            for(int j=3*i;j<10002;j+=2*i){
                notp[j]=true;
            }
            pheap[plen++]=i;
        }
    }
}
void calc(int n){
    times=0;
    for(int i=0;i<plen&&n>1;i++){
        while(n%pheap[i]==0){
            heap[times++]=pheap[i];
            n/=pheap[i];
        }
    }
    if(n>1)heap[times++]=n;
}
long long calphi(int num){
    assert(num>0);
    if(num==1)return 1;
    long long a=num;
    for(int i=0,f=-1;i<times;i++){
        if((f==-1||(f!=-1&&heap[i]!=heap[f]))&&num%heap[i]==0)a=a/heap[i]*(heap[i]-1);
        f=i;
    }
    return a;
}
void dfs(int gcd,int ind){
    sum+=calphi(n/gcd);
   // long long b=qpow(gcd);
//printf("+%d a %I64d b %d\n",a*b,a,b);
    ans+=calphi(n/gcd)*qpow(gcd)%mod;
    for(int i=ind+1,f=-1;i<times;i++){
        if(f!=-1&&heap[f]==heap[i]){continue;}
        f=i;
        dfs(gcd*heap[i],i);
    }
}
void solve(){
    ans=0;
    calc(n);
    dfs(1,-1);
    ans%=mod;
    printf("%d\n",(int)ans);
}
int main(){
    getprime();
    int t;
    scanf("%d",&t);
    while(t--){
        scanf("%d%d",&k,&n);
        solve();
    }
    return 0;
}

时间限制 1000 ms  内存限制 65536 KB

题目描述

Study sister plays the game coc everyday. It is very popular among the young people. In the game,you can own a clan and you
should launch a attack to promote your level.Now we make this game a little bit different. You are the King and have the power to lead the kings of every clan to attack each others.In the world of “CoC”,there exist many clan and many directed road between them. In order to cut down the cost of weapons and other supplies,someclans choose to ally with other clans. Some clans will make an union if they can reach each other. The clans in the same union won't attack each other and they can attack other union's clan together. If you want to attack a clan,just let a member of your union(including yourself) attack any clans in its union. In another words,if a kingA want to attack kingB and kingA has a alliance kingC while kingB has a alliance king D, there are 4 possible ways to launch this attak:
1.kingA attack kingB
2.kingA attack kingD
3.kingC attack kingB
4.kingC attack kingD
As we all know every union attaches importance to the land, they will attack the troop which passes their clan and is not belong to it's union. Here comes the problem, you are so mercy that you don't want to let the innocent citizens suffer from the wars. As a result, you have to give the king who wants to attack the others an number K which represents the number of the unavoidable attack to the innocentuinons on his way to attack his goal. If a king can't meet with this rule,he can't launch this attack.

输入格式

There are multiple cases. (T<=1000)
For each case:
The first line: 
three integers N M K  (N<=2000,M<=4000 ,k<=3000)
(N means the number of clans.M means the number of the roads
between the clans.K means the limitation you give)
The following M line: 
each line exists two integer X Y (means there is a
road between the clanX and clanY. The clans are numbered
from 1 to N)
The last line: 
two integers A B (means kingA want to attack kingB)

输出格式

If kingA and kingB belong to the same union, print“Input Error”
If kingA can launch this attack, print “Good Job”
If kingA can't launch this attack, print “Sad”

 

输入样例

1
6 6 2
1 4
4 5 
5 1
2 3
3 6
4 6
1 3

输出样例

Sad
思路:强连通分量
卡住原因:记录遍历次序的时候实际上每个点是可以遍历多次的

#include<cstdio>
#include <algorithm>
#include <vector>
#include <assert.h>
#include <queue>
#include <cstring>
using namespace std;
const int maxm=4001;
const int maxn=2001;
const int inf =0x7fffffff;
 
int n,m,k;
bool vis[maxn];
int par[maxn];
vector<int >G[maxn];
vector<int >rG[maxn];
int rs[40000];
int rlen;
int d[maxn];
int len[maxn];
void dfs(int s){
    //assert(!vis[s]);
    vis[s]=true;
    int siz=G[s].size();
    for(int i=0;i<siz;i++){
        if(!vis[G[s][i]])dfs(G[s][i]);
    }
    rs[rlen++]=s;
}
void rdfs(int s,int ind){
    //assert(!vis[s]);
    vis[s]=true;
    par[s]=ind;
    int siz=rG[s].size();
    for(int i=0;i<siz;i++){
        if(!vis[rG[s][i]]){
                rdfs(rG[s][i],ind);
        }
    }
}
queue <int > que;
int spfa(int s,int e){
    fill(d,d+n+1,inf);
    d[s]=0;
    que.push(s);
    while(!que.empty()){
        int f=que.front();que.pop();
        vis[f]=false;
        for(int i=0;i<G[f].size();i++){
            int t=G[f][i];
            if(par[t]==par[f]){
                if(d[t]>d[f]){
                    d[t]=d[f];
                    if(!vis[t]){
                            que.push(t);
                            vis[t]=true;
                    }
                }
            }
            else if(d[t]>d[f]+1){
                d[t]=d[f]+1;
                if(!vis[t]){
                    que.push(t);
                    vis[t]=true;
                }
            }
        }
    }
    return d[e];
}
int main(){
    int t;
    scanf("%d",&t);
    while(t--){
        scanf("%d%d%d",&n,&m,&k);
        for(int i=0;i<=n;i++){
            G[i].clear();
            rG[i].clear();
        }
        memset(len,0,sizeof(len));
        for(int i=0;i<m;i++){
            int f,t;
            scanf("%d%d",&f,&t);
            G[f].push_back(t);
            rG[t].push_back(f);
        }
        int s,e;
        scanf("%d%d",&s,&e);
        memset(vis,0,sizeof(vis));
        for(int i=1;i<=n;i++){
            if(!vis[i])dfs(i);
        }
        memset(vis,0,sizeof(vis));
        memset(par,0,sizeof(par));
        for(int i=rlen-1,ind=0;i>=0;i--){
            if(!vis[rs[i]])rdfs(rs[i],ind++);
        }
        if(par[s]==par[e]){
            printf("Input Error\n");
            continue;
        }
        memset(vis,0,sizeof(vis));
        int ans=spfa(s,e);
        if(ans<=k)printf("Good Job\n");
        else printf("Sad\n");
    }
    return 0;
}




你可能感兴趣的:(北邮还是新生吗训练赛12)