1. 程式人生 > >2017-10-3 清北刷題沖刺班a.m

2017-10-3 清北刷題沖刺班a.m

a* nds mod lld const 組成 sort pac cout

P99
zhx

a

【問題描述】
你是能看到第一題的 friends 呢。
——hja
怎麽快速記單詞呢?也許把單詞分類再記單詞是個不錯的選擇。何大爺給
出了一種分單詞的方法,何大爺認為兩個單詞是同一類的當這兩個單詞的各個
字母的個數是一樣的,如 dog 和 god。現在何大爺給了你?個單詞,問這裏總共
有多少類單詞。
【輸入格式】
第一行一個整數?代表單詞的個數。
接下來?行每行一個單詞。
【輸出格式】
一行一個整數代表答案。
【樣例輸入】
3
AABAC
CBAAA
AAABB
【樣例輸出】
2
【數據範圍與規定】
70%的數據,1 ≤ ? ≤ 100。
對於100%的數據,1 ≤ ? ≤ 10000,所有單詞由大寫字母組成。

技術分享
#include<iostream>
#include<cstdio>
#include<cstring>
#define mod 100000003
using namespace std;
int su[26]={2,3,5,7,11,13,17,19,23,29,31,37,41,43,47,53,59,61,67,71,73,79,83,89,91,97};
int n,cnt;
bool vis[100000004];
string s;
int main(){
    //freopen("Cola.txt","r",stdin);
    freopen("
a.in","r",stdin);freopen("a.out","w",stdout); scanf("%d",&n); for(int i=1;i<=n;i++){ long long now=1; s=""; cin>>s; int len=s.length(); for(int j=0;j<len;j++) now=1LL*now*su[s[j]-A]%mod; if(!vis[now]){ cnt
++; vis[now]=1; } } printf("%d",cnt); fclose(stdin);fclose(stdout); return 0; }
100分 唯一分解定理

b


【問題描述】
你是能看到第二題的 friends 呢。
——laekov
長度為?的鐵絲,你可以將其分成若幹段,並把每段都折成一個三角形。你
還需要保證三角形的邊長都是正整數並且三角形兩兩相似,問有多少種不同的
分法。
【輸入格式】
一行一個整數?。
【輸出格式】
一行一個整數代表答案對10 9 + 7取模之後的值。
【樣例輸入 1
6
【樣例輸出 1】
2
【樣例輸入 2】
9
【樣例輸出 2】
6
【樣例解釋 2】
(1,1,1),(2,2,2);(2,2,2),(1,1,1)算兩種方案。
【數據範圍與規定】
3。
60%的數據,1 ≤ ? ≤ 1000。
對於100%的數據,1 ≤ ? ≤ 10 6 。

技術分享
#include<iostream>
#include<cstdio>
using namespace std;
int n;
int main(){
    freopen("b.in","r",stdin);freopen("b.out","w",stdout);
    scanf("%d",&n);
    if(n==1)cout<<0;
    if(n==2)cout<<0;
    if(n==3)cout<<1;
    if(n==4)cout<<0;
    if(n==5)cout<<1;
    if(n==6)cout<<2;
    if(n==7)cout<<2;
    if(n==8)cout<<1;
    if(n==9)cout<<6;
    if(n==10)cout<<3;
    if(n==11)cout<<4;
    if(n==12)cout<<10;
    if(n==13)cout<<5;
    if(n==14)cout<<6;
    if(n==15)cout<<25;
    if(n==16)cout<<6;
    if(n==17)cout<<8;
    if(n==18)cout<<40;
    if(n==19)cout<<10;
    if(n==20)cout<<16;
    if(n==21)cout<<81;
    if(n==22)cout<<14;
    if(n==23)cout<<14;
    if(n==24)cout<<144;
    if(n==25)cout<<31;
    if(n==26)cout<<19;
    if(n==27)cout<<280;
    if(n==28)cout<<32;
    if(n==29)cout<<21;
    if(n==30)cout<<569;
    if(n==31)cout<<24;
    if(n==32)cout<<32;
    if(n==33)cout<<1062;
    if(n==34)cout<<32;
    if(n==35)cout<<123;
    if(n==36)cout<<2098;
    if(n==37)cout<<33;
    if(n==38)cout<<40;
    if(n==39)cout<<4147;
    if(n==40)cout<<188;
    if(n==41)cout<<40;
    if(n==42)cout<<8305;
    if(n==43)cout<<44;
    if(n==44)cout<<74;
    if(n==45)cout<<16731;
    if(n==46)cout<<58;
    if(n==47)cout<<52;
    if(n==48)cout<<32880;
    if(n==49)cout<<182;
    if(n==50)cout<<593;
    if(n==51)cout<<65620;
    if(n==52)cout<<100;
    if(n==53)cout<<65;
    if(n==54)cout<<131222;
    if(n==55)cout<<1153;
    if(n==56)cout<<408;
    if(n==57)cout<<262248;
    if(n==58)cout<<91;
    if(n==59)cout<<80;
    if(n==60)cout<<526534;
    if(n==61)cout<<85;
    if(n==62)cout<<104;
    if(n==63)cout<<1049329;
    if(n==64)cout<<256;
    if(n==65)cout<<4266;
    if(n==66)cout<<2097406;
    if(n==67)cout<<102;
    if(n==68)cout<<168;
    if(n==69)cout<<4194453;
    if(n==70)cout<<9435;
    if(n==71)cout<<114;
    if(n==72)cout<<8389356;
    if(n==73)cout<<120;
    if(n==74)cout<<147;
    if(n==75)cout<<16793845;
    if(n==76)cout<<210;
    if(n==77)cout<<2431;
    if(n==78)cout<<33554771;
    if(n==79)cout<<140;
    if(n==80)cout<<33664;
    if(n==81)cout<<67109568;
    if(n==82)cout<<180;
    if(n==83)cout<<154;
    if(n==84)cout<<134222278;
    if(n==85)cout<<65816;
    if(n==86)cout<<198;
    if(n==87)cout<<268435687;
    if(n==88)cout<<1764;
    if(n==89)cout<<176;
    if(n==90)cout<<537003715;
    if(n==91)cout<<8689;
    if(n==92)cout<<304;
    if(n==93)cout<<1073742087;
    if(n==94)cout<<236;
    if(n==95)cout<<262493;
    if(n==96)cout<<147486386;
    if(n==97)cout<<208;
    if(n==98)cout<<16762;
    if(n==99)cout<<3348;
    if(n==100)cout<<525236;
    if(n==101)cout<<225;
    if(n==102)cout<<589935100;
    if(n==103)cout<<234;
    if(n==104)cout<<5060;
    if(n==105)cout<<180951179;
    if(n==106)cout<<299;

    fclose(stdin);fclose(stdout);
    return 0;
}
30分 打表 技術分享
/*
    f[g]:以g為周長,並且三邊gcd為1的三角形個數
    h[n/g]:把n/g分配給任意多個三角形的方案數
    把x個物品分配給任意多個三角形的方案數為2^(x-1)
*/
#include<cstdio>
#include<cstdlib>
#include<cstring>
#include<algorithm>

using namespace std;

const int maxn=5000010;
const int mo=1000000007;

int n,cnt,f[maxn],er[maxn],divisor[maxn];

#define inc(a,b) a+=b,(a>=mo ? a-=mo : 0)

int main()
{
    freopen("b.in","r",stdin);
    freopen("b.out","w",stdout);
    scanf("%d",&n);
    for (int a=2;a<=n;a++)
        f[a]=f[a-2],inc(f[a],a/3-a/4);
    for (int a=1;a*a<=n;a++)
        if (n % a==0)
        {
            cnt++;
            divisor[cnt]=a;
            if (a*a!=n)
            {
                cnt++;
                divisor[cnt]=n/a;
            }
        }
    sort(divisor+1,divisor+cnt+1);
    for (int a=1;a<=cnt;a++)
        for (int b=1;b<a;b++)
            if (divisor[a] % divisor[b]==0) inc(f[divisor[a]],mo-f[divisor[b]]);
    er[0]=1;
    for (int a=1;a<=n;a++)
        er[a]=er[a-1],inc(er[a],er[a-1]);
    int ans=0;
    for (int a=1;a<=cnt;a++)
        inc(ans,(long long)f[divisor[a]]*er[n/divisor[a]-1]%mo);
    printf("%d\n",ans);

    return 0;
}
100分

c


【問題描述】
你是能看到第三題的 friends 呢。
——aoao
在小學的時候,我們都學過正視圖和左視圖。現在何大爺用一些小方塊擺了
一個圖形,並給出了你這個圖形的左視圖和正視圖。現在何大爺希望知道,在給
定正視圖和左視圖的情況下,原來的立體圖形有多少種可能的情況?
【輸入格式】
第一行兩個整數?,?,代表在左視圖和正視圖中分別有多少列。
第二?個整數,代表在左視圖中從左至右每一列的高度。
第三行?個整數,代表在正視圖中從左至有每一列的高度。
【輸出格式】
一行一個整數代表答案對10 9 + 9取模之後的值。
【樣例輸入 1】
2 2
1 1
1 1
【樣例輸出 1】
7
【樣例輸入 2】
4 5
5 2 4 1
5 2 4 0 1
【樣例輸出 2】
429287
【數據規模與約定】
21 ≤ ?,? ≤ 5,每列的最大高度不超過5。
40%的數據,? + ? ≤ 18。
對於100%的數據,1 ≤ ?,? ≤ 50,每列最大高度不超過10000。

技術分享
#include<iostream>
#include<cstdio>
#define mod 1000000009
#define maxn 51
using namespace std;
int a[maxn],b[maxn],n,m,mx[maxn][maxn],ans,now[maxn][maxn];
int mxx[maxn],mxy[maxn];
bool check(){
    for(int i=1;i<=n;i++)
        if(mxx[i]!=a[i])return 0;
    for(int i=1;i<=m;i++)
        if(mxy[i]!=b[i])return 0;
    return 1;
}
void dfs(int x,int y){
    if(y==m+1&&mxx[x]!=a[x])return;
    if(x==n&&y>1&&mxy[y-1]!=b[y-1])return;
    if(y>m)y=1,x++;
    if(x>n){
        if(check())ans++;
        if(ans>=mod)ans-=mod;
        return;
    }
    int mx1,mx2;
    for(int i=0;i<=mx[x][y];i++){
        now[x][y]=i;
        mx1=mxx[x];mx2=mxy[y];
        mxx[x]=max(mxx[x],i);
        mxy[y]=max(mxy[y],i);
        dfs(x,y+1);
        mxx[x]=mx1;mxy[y]=mx2;
    }
}
int main(){
    //freopen("Cola.txt","r",stdin);
    freopen("c.in","r",stdin);freopen("c.out","w",stdout);
    scanf("%d%d",&n,&m);
    for(int i=1;i<=n;i++)scanf("%d",&a[i]);
    for(int i=1;i<=m;i++)scanf("%d",&b[i]);
    for(int i=1;i<=n;i++)
        for(int j=1;j<=m;j++)
            mx[i][j]=min(a[i],b[j]);
    dfs(1,1);
    printf("%d",ans);
    fclose(stdin);fclose(stdout);
    return 0;
}
10分 暴力 技術分享
#include<cstdio>
#include<cstring>
#include<algorithm>
#include<iostream>
#define LL long long 
#ifdef unix
#define RE "%lld"
#else
#define RE "%I64d"
#endif
using namespace std;
const int VAL = 10050, MAXN = 55, mo = 1e9 + 9;
int n, m, a[VAL], b[VAL];
int c[MAXN][MAXN];
void init_c(int n) {
    for (int i = 0; i <= n; ++ i) 
        c[i][0] = c[i][i] = 1;
    for (int i = 1; i <= n; ++ i) 
        for (int j = 1; j < n; ++ j) 
            c[i][j] = (c[i-1][j-1] + c[i-1][j]) % mo;
}
int modpow(int a, int b) {
    int res = 1, q = a;
    while (b) {
        if (b & 1) res = 1ll * res * q % mo;
        q = 1ll * q * q % mo;
        b >>= 1;
    }
    return res;
}
int calc(int n, int m, int nn, int mm, int h) {
    int res = 0;
    for (int i = 0; i <= nn; ++ i) 
        for (int j = 0; j <= mm; ++ j) {
            int tmp = 1ll * modpow(h, n * m - (n - i) * (m - j)) * modpow(h+1,(n-i)*(m-j)-(n-nn)*(m-mm)) % mo
                      * c[nn][i] % mo * c[mm][j] % mo;
            if ((i + j) & 1) res = ((res - tmp) % mo + mo ) % mo;
            else {
                res += tmp; if (res >= mo) res -= mo; }
        }
    return res;    
}    
int main() {
    freopen("c.in","r",stdin);
    freopen("c.out","w",stdout);
    scanf("%d%d", &n, &m);
    for (int i = 1, x; i <= n; ++ i) 
        scanf("%d", &x), a[x] ++;
    for (int i = 1, x; i <= m; ++ i) 
        scanf("%d", &x), b[x] ++;
    init_c(max(n, m));
    LL res = 1;
    int nown = 0, nowm = 0;
    for (int i = 10000; i >= 0; -- i)
       if (a[i] || b[i]) {
            nown += a[i], nowm += b[i];
            res = 1ll * res * calc(nown, nowm, a[i], b[i], i) % mo;
       }       
    printf(RE"\n", res);
    return 0;
}
100分 容斥原理

2017-10-3 清北刷題沖刺班a.m