zoukankan      html  css  js  c++  java
  • 串 & 容斥原理

    题意:

      给出n (n<=50000) 个长度为4的字符串,问有且仅有d(1<=d<=4)不相同的字符串有几对。

    SOL:

      一直对着4发呆,这么小的字符串背后有什么玄学呢= =...既不能放在TRIE上搞似乎也套不了什么东西,一直很好奇这种题目能不能用某个神奇的字符串HASH水过...然后颓了一会儿突然想到,如果我们只是判断字符串相等不相等的话,因为每个位置只有36种状态,直接开个36^4的数组加加减减然后搞个组合数就好了.

      

      那不是可以迁移过来吗?!!!!!!!

      

      在那个问题之上,我们要解决的是两个字符串之间不同的个数---->考虑到我们可以把一个字符串拆成其按顺序的各个排列组合,然后就变成了上面的那个判定性的问题.分开来好判断,怎么把它合起来呢?容斥啊傻吊...虽然这是在OI上打的第一个容斥不过还是非常..显然?...

    CODE:

      

    /*==========================================================================
    # Last modified: 2016-02-27 09:13
    # Filename: t2.cpp
    # Description:
    ==========================================================================*/
    #define me AcrossTheSky
    #include <cstdio>
    #include <cmath>
    #include <ctime>
    #include <string>
    #include <cstring>
    #include <cstdlib>
    #include <iostream>
    #include <algorithm>
        
    #include <set>
    #include <map>
    #include <stack>
    #include <queue>
    #include <vector>
       
    #define lowbit(x) (x)&(-x)
    #define FOR(i,a,b) for((i)=(a);(i)<=(b);(i)++)
    #define FORP(i,a,b) for(int i=(a);i<=(b);i++)
    #define FORM(i,a,b) for(int i=(a);i>=(b);i--)
    #define ls(a,b) (((a)+(b)) << 1)
    #define rs(a,b) (((a)+(b)) >> 1)
    #define getlc(a) ch[(a)][0]
    #define getrc(a) ch[(a)][1]
       
    #define maxn 40
    #define maxm 100000
    #define pi 3.1415926535898
    #define _e 2.718281828459
    #define INF 1070000000
    using namespace std;
    typedef long long ll;
    typedef unsigned long long ull;
       
    template<class T> inline
    void read(T& num) {
        bool start=false,neg=false;
        char c;
        num=0;
        while((c=getchar())!=EOF) {
            if(c=='-') start=neg=true;
            else if(c>='0' && c<='9') {
                start=true;
                num=num*10+c-'0';
            } else if(start) break;
        }
        if(neg) num=-num;
    }
    /*==================split line==================*/
    int a[5];
    ll sum[maxn][maxn][maxn][maxn],ans[10];
    bool check(char c){ if (c>='0' && c<='9') return false; return true;}
    void init(char *s){
        FORP(i,0,15){
            FORP(j,0,3)
                if (i & 1<<j) a[j]=check(s[j])?s[j]-'a'+10:s[j]-'0';
                else a[j]=36;
            //FORP(i,0,3) printf("%d ",a[i]); printf("
    ");
            sum[a[0]][a[1]][a[2]][a[3]]++;
        }
        //printf("
    ");
    }
    int judge(int x){if (x<36) return 1; else return 0;}
    void solve(){
        FORP(k,0,36)
            FORP(l,0,36)
                FORP(m,0,36)
                    FORP(n,0,36){
                        ll f=judge(k)+judge(l)+judge(m)+judge(n),p=sum[k][l][m][n];
                        ans[f]+=(p*(p-1)/2);
                    }                 
    }
    int main(){
        ll n,d; read(n); read(d);
        FORP(i,1,n){
            char s[10];
            scanf("%s",s);
            init(s);
        }
        solve();
        //FORP(i,0,4) printf("%d ",ans[i]);
        //cout << endl;
        //FOR(d,1,4){
        if (d==1) printf("%lld
    ",ans[3]-4*ans[4]);
        if (d==2) printf("%lld
    ",ans[2]-3*ans[3]+6*ans[4]);
        if (d==3) printf("%lld
    ",ans[1]-2*ans[2]+3*ans[3]-4*ans[4]);
        if (d==4) printf("%lld
    ",ans[0]-ans[1]+ans[2]-ans[3]+ans[4]);
        //}
    }
    
    Sometimes it s the very people who no one imagines anything of. who do the things that no one can imagine.
  • 相关阅读:
    0.1.3 set的用法
    JoinPoint
    砝码组合(dfs)
    强大的【环绕通知】
    applicationContext.xml 模板
    各种jar包
    装饰博客(二)添加宠物
    装饰博客(一)添加背景图片
    拖拽功能的实现
    点击之后连接qq
  • 原文地址:https://www.cnblogs.com/YCuangWhen/p/5222903.html
Copyright © 2011-2022 走看看