zoukankan      html  css  js  c++  java
  • 模板

    #include<bits/stdc++.h>
    using namespace std;
    typedef long long ll;
    const int M = 1500 + 10;
    int n,x,y;
    struct node {
        int xx,yy,id;
        bool operator < (const node &a) const {
            if(xx-x>=0 && a.xx-x<=0) return 1;
            if(xx-x<=0 && a.xx-x>=0) return 0;
            return (yy-y)*(ll)(a.xx-x)<(a.yy-y)*(ll)(xx-x);
        }
    }p[M];
    
    vector<int> g[M];
    int sz[M];
    int ans[M];
    
    void dfs (int o,int u) {
        sz[u] = 1;
        for (int &v : g[u]) if (v!=o) {
            dfs (u, v);
            sz[u] += sz[v];
        }
    }
    
    void dfs2 (int o,int u,int l,int r) {
        if (sz[u]==1) {
            ans[p[l].id] = u;
            return;
        }
        int id=l;
        for (int i=l+1; i<r; ++i) {
            if (p[i].xx < p[id].xx) {
                id = i;
            }
        }
        swap(p[id], p[l]);
        ans[p[l].id] = u;
        x=p[l].xx, y=p[l].yy;
        sort (p+l+1, p+r);
        int sum = l+1;
        for (int &v : g[u]) if (v!=o) {
            dfs2 (u, v, sum, sum+sz[v]);
            sum += sz[v];
        }
    }
    
    int main () {
        scanf ("%d", &n);
        for (int i=1,u,v; i<n; ++i) {
            scanf ("%d%d", &u,&v);
            g[u].emplace_back(v);
            g[v].emplace_back(u);
        }
        for (int i=0; i<n; ++i) {
            scanf ("%d%d", &p[i].xx, &p[i].yy);
            p[i].id = i;
        }
        dfs (1, 1);
        dfs2 (1, 1, 0, n);
        for (int i=0; i<n; ++i) {
            printf ("%d%c", ans[i], " 
    "[i==n-1]);
        }
        return 0;
    }
    极角排序
    #include<bits/stdc++.h>
    using namespace std;
    const int M = 2000+10;
    typedef vector<int> vec;
    vec g[M];
    vec rg[M];
    vec vs;
    bool used[M];
    int cmp[M];
    int n;
    
    void dfs (int u) {
        used[u] = true;
        for (int &v : g[u]) if (!used[v]) {
            dfs (v);
        }
        vs.emplace_back(u);
    }
    
    void rdfs (int u,int k) {
        used[u] = true;
        cmp[u] = k;
        for (int &v : rg[u]) if (!used[v]) {
            rdfs (v, k);
        }
    }
    
    int scc() {
        memset (used, false, sizeof(used));
        vs.clear();
        for (int v=0; v<n; ++v) {
            if (!used[v]) dfs (v);
        }
        memset (used, 0, sizeof(used));
        int k = 0;
        for (int i=vs.size()-1; i>=0; --i) {
            if (!used[vs[i]]) rdfs (vs[i], k++);
        }
        //printf ("%d
    ",k);
        return k;
    }
    
    int main () {
        scanf ("%d", &n);
        for (int i=0; i<n; ++i) {
            for (int j=0; j<n; ++j) {
                int x;
                scanf ("%d", &x);
                if (x) {
                    g[i].emplace_back(j);
                    rg[j].emplace_back(i);
                }
            }
        }
        printf ("%s
    ", scc()==1?"YES" : "NO");
        return 0;
    }
    强联通
     1 vector<bool> isprime;
     2 vector<int> mu;
     3 void sieve () {
     4     isprime.assign(M, true);
     5     isprime[0] = isprime[1] = false;
     6     for (int i=2; i<M/i; ++i) if (isprime[i]) {
     7         for (int j=i*i; j<M; j+=i) {
     8             isprime[j] = false;
     9         }
    10     }
    11     mu.assign(M, 1);
    12     for (int i=2; i<M; ++i) if (isprime[i]) {
    13         if (i<M/i) {
    14             for (int j=i*i; j<M; j+=i*i) mu[j] = 0;
    15         }
    16         for (int j=i; j<M; j+=i) mu[j] *= -1;
    17     }
    18 }
    埃筛 && 莫比乌斯函数
    import java.math.BigInteger;
    
    import java.util.Scanner;
    
    public class Main {
    
    public static void main(String[] args) {
            Scanner cin=new Scanner(System.in);
            BigInteger a,b;
    
            BigInteger big1=BigInteger.ZERO;//0 声明一个大整数并常数值赋值0  
            BigInteger big2=BigInteger.ONE;//1  
            BigInteger big3=BigInteger.TEN;//10  
              
            BigInteger big4 =new BigInteger("1000");//赋除了0,1,10之外的常数值的方法一  
            BigInteger big5= BigInteger.valueOf(1000);//没有new赋除了之外的常数值的方法二  
            //BigInteger bi1 =  new BigInteger(55,new Random());  生成一个个随机的大整数  
              
            BigInteger [] f=new BigInteger [1005];//声明大整数数组,并赋值  
            f[1]=BigInteger.ZERO;  
            f[2]=BigInteger.ONE;  
            f[3]=f[2];  
            f[4]= BigInteger.valueOf(3);//a[4]=a[2].add(a[2].add(a[2]));  
            System.out.println(f[4]);  
    
            while(cin.hasNext()) {
                a=cin.nextBigInteger();
                b=cin.nextBigInteger();
                System.out.println(a.add(b));//输出a+b
                System.out.println(a.subtract(b));//输出a-b
                System.out.println(a.multiply(b));//输出a*b
                System.out.println(a.divide(b));//输出a/b
                System.out.println(a.remainder(b));//输出a%b
                if(a.compareTo(b)==0)System.out.println("a==b");
                if(a.compareTo(b)>0)System.out.println("a>b");
                if(a.compareTo(b)<0)System.out.println("a<b");
                System.out.println(a.abs());//大数a的绝对值
                int exponent=cin.nextInt();
                System.out.println(a.pow(exponent)); //大整数a的exponent次幂
                 //返回大整数十进制的字符串表示
                System.out.println(a.toString());
                //返回大整数p进制的字符串表示
                int p=cin.nextInt();
                System.out.println(a.toString(p));
            }
        }
    }
    java BigInteger
    import java.math.*;
    import java.text.*;
    import java.util.Scanner;
    
    public class Main {
    
        public static void main(String[] args) {
            Scanner cin=new Scanner(System.in);
            int n;
            while(cin.hasNext())//等效于输入到文件尾
            {
                n = cin.nextInt();
                BigInteger fact = new BigInteger("1");
                BigInteger dp = new BigInteger("1");
                for (int i=2; i<=n; ++i) {
                    dp = dp.multiply(BigInteger.valueOf(i)).add(fact);
                    fact = fact.multiply(BigInteger.valueOf(i));
                }
                BigDecimal ans = new BigDecimal(dp);
                //BigInteger -> BigDecimal
                BigDecimal __fact = new BigDecimal(fact);
                //方法一
                //四舍五入到小数点后4位,格式“#.0000”
                DecimalFormat df = new DecimalFormat("#.0000");
                double zz = ans.divide(__fact,10, BigDecimal.ROUND_HALF_UP).doubleValue();
                System.out.println(df.format(zz));
                
                //方法二,全部输出
                //stripTrailingZeros() :用于去除末尾多余的0
                //toPlainString(): 控制不使用科学计数法输出
                System.out.println(ans.stripTrailingZeros().toPlainString());
            }
        }
    }
    BigDecimal
    //注意:因为 sam 在头部插入了一个 nill 字符(如果没有nill,right集会少
    //所以对于 parent树 的叶子:
    //如果 l(leaf) == l(fa(leaf)) + 1, 那么说明实际上从 fa(leaf) -> leaf这条边实际上是通过走 nill 字符通过的,
    //及原串实际上是不会走到这个节点的。
    //hdu6194
    #include<bits/stdc++.h>
    using namespace std;
    const int M = 1e5 + 10;
    char s[M];
    
    struct SAM {
        static const int kN = M << 1;
        static const int chN = 26;
        int fa[kN];
        int go[kN][chN];
        int l[kN];
        int o;
        int rt;
        int lst;
    
        inline int newNode(int _l) {
            for (int i=0; i<chN; ++i) {
                go[o][i] = -1;
            }
            l[o] = _l;
            return o ++;
        }
        void Init() {
            o = 0;
            rt = lst = newNode(0);
            fa[rt] = -1;
        }
        inline void InsKey() {
            int p = lst, np = newNode(l[lst]+1); lst = np;
            fa[np] = rt;
        }
        inline void Ins(int c) {
            int p = lst, np = newNode(l[lst]+1); lst = np;
            //printf ("%c:%d
    ", c+'a', np);
            while (~p && go[p][c] == -1) go[p][c] = np, p = fa[p];
            if (p==-1) fa[np] = rt;
            else {
                int q = go[p][c];
                if (l[p]+1 == l[q]) fa[np] = q;
                else {
                    int nq = newNode(l[p]+1);
                    //printf ("%c:%d
    ", c+'a', nq);
                    memcpy(go[nq], go[q], sizeof(go[q]));
                    fa[nq] = fa[q];
                    fa[q] = fa[np] = nq;
                    while (~p && go[p][c] == q) go[p][c] = nq, p = fa[p];
                }
            }
        }
    
        //topo
        int ord[kN];
        int cnt[kN];
        int right[kN];
        int in[kN];
        void topo() {
            int maxVal = 0;
            memset (cnt, 0, sizeof(cnt[0])*o);
            for (int i=0; i<o; ++i) maxVal = max(maxVal, l[i]), ++ cnt[l[i]];
            for (int i=1; i<=maxVal; ++i) cnt[i] += cnt[i-1];
            for (int i=0; i<o; ++i) ord[-- cnt[l[i]]] = i;
        }
    
        int solve(int k) {
            topo();
            memset (right, 0, sizeof(right[0])*o);
            memset (in, 0, sizeof(in[0])*o);
            for (int i=1; i<o; ++i) ++in[fa[i]];
            for (int i=1; i<o; ++i) right[i] = !in[i];
            for (int i=o-1; i>0; --i) right[fa[ord[i]]] += right[ord[i]];
            int ret = 0;
            for (int i=1; i<o; ++i) {
                if (k == right[i]) ret += l[i]-l[fa[i]]-(in[i]==0);
            }
            return ret;
        }
    } sam;
    
    int main () {
        int CASE;
        scanf ("%d", &CASE);
        while (CASE --) {
            int k;
            scanf ("%d%s", &k, s);
            sam.Init();
            sam.InsKey();
            for (int i=0; s[i]; ++i) {
                sam.Ins(s[i]-'a');
            }
            printf ("%d
    ", sam.solve(k));
        }
        return 0;
    }
    sam
    #include <stdio.h>
    #include <numeric>
    #include <time.h>
    #include <bitset>
    #include <string.h>
    #include <stack>
    #include <algorithm>
    #include <iostream>
    #include <set>
    #include <map>
    #include <math.h>
    #include <queue>
    #include <complex>
    #include <functional>
    #include <limits.h>
    using namespace std ;
    typedef long long ll ;
    typedef long double ld ;
    typedef unsigned long long ull ;
    #ifdef _WIN32
    #define LLD "%I64d"
    #else
    #define LLD "%lld"
    #endif
    #define pi (acos(-1.0))
    #define fi first
    #define se second
    #define SZ(x) ((int)x.size())
    #define lson (o<<1),l,mid
    #define rson (o<<1|1),mid+1,r
    #define MP make_pair
    #define sqr(x) ((x)*(x))
    #define ALL(v) (v).begin(),(v).end()
    #define showtime fprintf(stderr,"time = %.15f
    ",clock() / (double)CLOCKS_PER_SEC)
    const double eps = 1e-9 ;
    const int MOD=(int)1e9+7,BAS=233;
    inline int sign(double x){return x<-eps?-1:x>eps;}
    inline int clz(int x){return __builtin_clz(x);}
    inline int clz(ll x){return __builtin_clzll(x);}
    inline int lg2(int x){return !x ? -1 : 31-clz(x);}
    inline int lg2(ll x){return !x ? -1 : 63-clz(x);}
    int AP (char *s) {
        unsigned hash=0;
        for(int i=0; s[i]; i++){
            if (i & 1) hash ^= (~((hash<<11)^s[i]^(hash>>5)));
            else hash ^= ((hash<<7)^s[i]^(hash>>3));
       } return hash & 0x7FFFFFFF;
    }
    
    const int M=2000000+10, nill=0;
    int ls[M], rs[M], rt;
    int b[M];
    
    struct Node {
        int sz;
        unsigned fix;
        int v;
        int mk;
        void init (int _v) {
            v = _v;
            mk = 0;
        }
        void mark (int _mk) {
            mk += _mk;
            v += _mk;
        }
    }T[M];
    
    int MY;
    
    struct Treap {
        inline unsigned ran () {
            static unsigned fix = 91250681;
            return fix += fix << 2 | 1;
        }
        inline int alloc (int _v) {
            T[MY].init(_v); T[MY].sz=1; T[MY].fix=ran(); ls[MY]=rs[MY]=nill;
            return MY++;
        }
        inline void down (int o) {
            if (T[o].mk == 0) return;
            T[ls[o]].mark (T[o].mk);
            T[rs[o]].mark (T[o].mk);
            T[o].mk = 0;
        }
        inline void up (int o) {
            T[o].sz = T[ls[o]].sz + T[rs[o]].sz + 1;
        }
        void cut (int o,int &a,int &b,int k) {
            if (T[o].sz<=k) {a=o,b=nill;return;}
            if (k<=0) {a=nill,b=o;return;}
            down (o);
            if (k>T[ls[o]].sz) cut (rs[o],rs[a=o],b,k-T[ls[o]].sz-1);
            else cut (ls[o],a,ls[b=o],k);
            up(o);
        }
        void Merge (int &o,int a,int b) {
            if (a==nill) o=b;
            else if (b==nill) o=a;
            else if (T[a].fix>T[b].fix) {
                down(a);
                Merge(rs[o=a],rs[a],b);
                up(o);
            } else {
                down(b);
                Merge(ls[o=b],a,ls[b]);
                up(o);
            }
        }
        int lower (int o,int v) {//求大于等于v的数的个数
            if (o == nill) return 0;
            down(o);
            if (T[o].v < v) {
                return lower (rs[o], v);
            } else {
                return 1 + T[rs[o]].sz + lower (ls[o], v);
            }
        }
        void build (int &o,int l,int r) {
            if (l > r) return;
            int mid = l + r>>1;
            o = alloc (b[mid]);
            build (ls[o], l, mid-1); build (rs[o], mid+1, r);
            up (o);
        }
        void del (int v) {//删除已经存在于集合中的数v
            int num = T[rt].sz - lower (rt, v);
            int a, b, c;
            cut (rt, a, b, num);
            cut (b, b, c, 1);
            Merge (rt, a, c);
        }
        void ins (int v) {
            int num = T[rt].sz - lower (rt, v);
            //printf ("num = %d
    ", num);
            int a, b, c;
            cut (rt, a, b, num);
            c = alloc(v);
            Merge (rt, a, c);
            Merge (rt, rt, b);
            //printf ("ls:%d , rs:%d
    ", T[ls[c]].v, T[rs[c]].v);
        }
        void update () {
            T[rt].mark(-1);
        }
        void Print (int o) {
            if (o==nill) return;
            down (o);
            //printf ("%d: %d, %d
    ", T[o].v, T[ls[o]].v, T[rs[o]].v);
            //printf ("%d
    ", T[o].sz);
            Print (ls[o]);
            printf ("%d ", T[o].v);
            Print (rs[o]);
        }
        void Clear () {
            rt = nill;
            T[rt].sz = 0; ls[rt] = rs[rt] = nill;
            MY = 1;
        }
    } my;
    
    int n;
    int a[M];
    
    int main () {
        //srand(time(0));
        my.Clear();
        scanf ("%d", &n);
        ll now = 0;
        for (int i=1; i<=n; ++i) {
            scanf ("%d", a+i);
            now += abs(a[i] - i);
            //my.ins(a[i] - i);
            b[i] = a[i] - i;
        }
        sort (b+1, b+1+n);
        my.build (rt, 1, n);
        ll minn = now;
        int k = 0;
        //printf ("%d: %I64d
    ", 0, now);
        for (int i=n, j=0; i>=1 && j<300000; --i, ++j) {
            //my.Print(rt);
            now -= abs(a[i] - n);
            now += abs(a[i] - 1);
            my.del(a[i] - n);
            int f = my.lower (rt, 1);
            //printf ("f=%d, a[%d]=%d
    ", f, i, a[i]);
            now += (T[rt].sz - f) - f;
            printf ("%d: %I64d
    ", i, now);
            if (now < minn) {
                k = n-i+1;
                minn = now;
            }
            my.update();
            my.ins(a[i] - 1);
        }
        printf ("%I64d %d
    ", minn, k);
        return 0;
    }
    /*
    10
    10 1 9 2 8 3 7 4 6 5
    */
    treap
    #include <bits/stdc++.h>
    using namespace std;
    
    const int N = 1e2 + 5;
    const double EPS = 1e-10;
    int sign(double x) {  //三态函数,减少精度问题
        return abs(x) < EPS ? 0 : x < 0 ? -1 : 1;
    }
    struct Point { //点的定义
        int x, y, id;
        Point(int x=0, int y=0) : x(x), y(y) {}
        Point operator + (const Point &rhs) const {  //向量加法
            return Point(x + rhs.x, y + rhs.y);
        }
        Point operator - (const Point &rhs) const {  //向量减法
            return Point(x - rhs.x, y - rhs.y);
        }
        Point operator * (int p) const {  //向量乘以标量
            return Point(x * p, y * p);
        }
        bool operator < (const Point &rhs) const {  //点的坐标排序
            return x < rhs.x || (x == rhs.x && y < rhs.y);
        }
        bool operator == (const Point &rhs) const {  //判断同一个点
            return x - rhs.x == 0 && y - rhs.y == 0;
        }
        void read() {
            scanf("%d%d", &x, &y);
        }
        void print() {
            printf("(%d, %d)
    ", x, y);
        }
    };
    typedef Point Vector;  //向量的定义
    typedef vector<Point> Polygon;  //多边形的定义。使用函数的前提:多边形poly排好序
    
    int cross(Vector A, Vector B) {  //向量叉积,两向量组成的三角形的有向面积的两倍,可判断两向量的方向
        return A.x * B.y - A.y * B.x;
    }
    
    /*
     *凸包,基于水平序的Andrew算法。输入点的集合,返回凸包点的集合。
     *凸包边上无点:<=;凸包边上有点:<
     *时间复杂度O(NlogN)
     */
    Polygon convex_hull(Polygon P) {
        sort(P.begin(), P.end());  //排序
        P.erase(unique(P.begin(), P.end()), P.end());  //删除重复点
        int n = P.size(), k = 0;
        Polygon Q(n*2);
        for (int i=0; i<n; ++i) {
            while (k > 1 && cross(Q[k-1]-Q[k-2], P[i]-Q[k-2]) < 0) k--;
            Q[k++] = P[i];
        }
        for (int t=k, i=n-2; i>=0; --i) {
            while (k > t && cross(Q[k-1]-Q[k-2], P[i]-Q[k-2]) < 0) k--;
            Q[k++] = P[i];
        }
        Q.resize(k-1);
        return Q;
    }
    
    Point p[N];
    Polygon poly;
    bool A[N];
    int n;
    
    int dot(Vector A, Vector B) {  //向量点积:向量长度的乘积再乘上夹角的余弦值,可判断两向量的角度
        return A.x * B.x + A.y * B.y;
    }
    
    double length(Vector A) {  //向量长度,点积
        return sqrt((double)dot(A, A));
    }
    
    bool spj() {
        if (n > 3) return false;
        Vector a = p[1] - p[0], b = p[2] - p[0];
        double x1 = a.x, y1 = a.y, x2 = b.x, y2 = b.y;
        double la = length(a), lb = length(b);
        x1 /= la; y1 /= la;
        x2 /= lb; y2 /= lb;
        return sign(x1-x2) == 0 && sign(y1-y2) == 0;
    }
    
    bool judge() {
        Polygon res = convex_hull(poly);
        int sz = res.size();
        if (sz == 3) {
            if (sz == n) {
                if (spj()) {  // 3 points in a line
                    A[p[0].id] = A[p[2].id] = true; return true;
                } else return false;
            } else {
                A[res[0].id] = A[res[1].id] = A[res[2].id] = true; return true;
            }
        } else {
            A[res[0].id] = A[res[2].id] = true;
            return true;
        }
    }
    
    int main() {
        int T;
        scanf("%d", &T);
        while (T--) {
            scanf("%d", &n);
            poly.clear();
            memset(A, false, sizeof(A[0])*(n+1));
            for (int i=0; i<n; ++i) {
                p[i].read();
                p[i].id = i;
                poly.push_back(p[i]);
            }
            sort(p, p+n);
            if (n < 3 || !judge()) puts("NO");
            else {
                puts("YES");
                for (int i=0; i<n; ++i) {
                    if (A[i]) printf("%c", 'A');
                    else printf("%c", 'B');
                }
                puts("");
            }
        }
        return 0;
    }
    凸包
    #include <cstdio>
    #include <cstring>
    #include <queue>
    using namespace std;
    const int N = 15;
    const int M = 362880;
    typedef long long LL;
    int n;
    LL src, tim;
    char str[N];
    int s[N], s1[N], s2[N];
    LL fac[N];
    int vis[M];
    queue <LL> que;
    void cantor(int s[], LL num, int k){//康托展开,把一个数字num展开成一个数组s,k是数组长度
        int t;
        bool h[k];//0到k-1,表示是否出现过
        memset(h, 0, sizeof(h));
        for(int i = 0; i < k; i ++){
            t = num / fac[k-i-1];
            num = num % fac[k-i-1];
            for(int j = 0, pos = 0; ; j ++, pos ++){
                if(h[pos]) j --;
                if(j == t){
                    h[pos] = true;
                    s[i] = pos + 1;
                    break;
                }
            }
        }
    }
    void inv_cantor(int s[], LL &num, int k){//康托逆展开,把一个数组s换算成一个数字num
        int cnt;
        num = 0;
        for(int i = 0; i < k; i ++){
            cnt = 0;
            for(int j = i + 1; j < k; j ++){
                if(s[i] > s[j]) cnt ++;//判断几个数小于它
            }
            num += fac[k-i-1] * cnt;
        }
    }
    
    int bfs(){
        if(src == tim) return 0;
        memset(vis, 0, sizeof(vis));
        while(!que.empty()) que.pop();
        que.push(src);
        que.push(0);
        vis[src] = 1;
        LL tmp, tmp2, dis;
        while(!que.empty()){
            tmp = que.front(); que.pop();
            dis = que.front(); que.pop();
            cantor(s, tmp, n);
            for(int i = 1; i < n; ++ i){
                swap(s[0], s[i]);
                inv_cantor(s, tmp2, n);
                swap(s[0], s[i]);
                if(vis[tmp2]) continue;
                if(tmp2 == tim) return dis+1;
                vis[tmp2] = 1;
                que.push(tmp2);
                que.push(dis+1);
            }
        }
    }
    
    int main(){
        fac[0] = 1;
        for(int i = 1; i < N; ++ i){
            fac[i] = fac[i-1] * i;
        }
        scanf("%d", &n);
        for(int cas = 1; cas <= 5; ++ cas){
            scanf("%s", str);
            for(int i = 0; i < n; ++ i){
                s[i] = str[i] - '1';
            }
            inv_cantor(s, src, n);
            scanf("%s", str);
            for(int i = 0; i < n; ++ i){
                s[i] = str[i] - '1';
            }
            inv_cantor(s, tim, n);
            
            int ans = bfs();
            printf("%d
    ", ans);
        }
    }
    康托展开
    ll solve(ll l,ll r) {
        while(r>l){
            ll m1=(2*l+r)/3;
            ll m2=(2*r+l+2)/3;
            ll ret1 = cal(m1);
            ll ret2 = cal(m2);
            //printf ("(%I64d, %I64d)
    ", m1, ret1);
            //printf ("(%I64d, %I64d)
    ", m2, ret2);
            if(ret1>ret2)
                r=m2-1;
            else
                l=m1+1;
        }
        return cal(l);
    }
    整型三分
    #include<cstdio>
    typedef long long LL;
    int n;
    LL dp[25];
    void init(){
        dp[1] = 0;
        dp[2] = 1;
        for(int i = 3; i <= 20; i ++){
            dp[i] = (i-1) * (dp[i-1] + dp[i-2]);
        }
    }
    int main(){
        init();
        while(~scanf("%d", &n)){
            printf("%I64d
    ", dp[n]);
        }
    }
    错排
    const int block = 233;
    struct Query {
        int l, r;
        int id;
        bool operator < (const Query &rhs) const {
            if (l/block == rhs.l/block) {
                return r < rhs.r;
            }
            return l < rhs.l;
        }
    }qu[M];
    
    void solve() {
        sort(qu, qu+m);
        l = r = nowAns = 0;
        for (int i = 0; i < m; ++i) {
            const Query &q = qu[i];
            while (l > q.l) Move(--l, 1);
            while (r < q.r) Move(++r, 1);
            while (l < q.l) Move(l++, -1);
            while (r > q.r) Move(r--, -1);
            ans[q.id] = nowAns;
        }
    }
    莫队
    #include<bits/stdc++.h>
    #define lson o<<1,l,mid
    #define rson o<<1|1,mid+1,r
    using namespace std;
    const int inf = 0x3f3f3f3f;
    const int N = ((int)3e5 + 5)<<1;
    char str[N];
    int a[N];
    
    struct Segtree {
        int T[N<<2];
        int up(int ls,int rs) {
            return min(ls, rs);
        }
        void build (int o,int l,int r) {
            if (l == r) {
                if (l & 1) T[o] = inf;
                else T[o] = l - (a[l]-1);
                //printf ("%d: %d
    ", l, T[o]);
                return;
            }
            int mid = l+r>>1;
            build (lson); build(rson);
            T[o] = up(T[o<<1], T[o<<1|1]);
        }
        int ask (int o,int l,int r,int pl,int pr,int id) {
            if (pl<=l && r<=pr) {
                if (T[o] > id) {
                    return -1;
                }
                if (l == r) return l;
            }
            int mid = l+r>>1;
            int ret = -1;
            if (pr>mid) ret = ask(rson,pl,pr,id);
            if (ret!=-1) return ret;
            if (pl<=mid) ret = ask(lson,pl,pr,id);
            return ret;
        }
    }sgt;
    
    char Ma[N];
    
    int Manacher(char s[], int len, int ret[]){
        char sep = '#';
        for(int i = 0; i < len; i ++){
            Ma[i << 1] = sep;
            Ma[i << 1 | 1] = s[i];
        }
        Ma[len << 1] = sep;
        len = len << 1 | 1;
        int R = 0, id = 0, Max = 0;
        for(int i = 0; i < len; i ++){
            if(R > i) ret[i] = min(ret[2*id-i], R-i);
            else ret[i] = 1;
            while(i-ret[i] >= 0 && i+ret[i] < len && Ma[i-ret[i]] == Ma[i+ret[i]]) ret[i]++;
            if(i+ret[i] > R){
                R = i+ret[i];
                id = i;
            }
            Max = max(Max, ret[i]-1);
        }
        return Max;
    }
    
    int main(){
        int n, len;
        scanf("%d", &n);
        for(int i = 0; i < n; i ++){
            scanf("%s", str);
            len = strlen(str);
            Manacher(str, len, a);
            //printf("%d
    ", Manacher(str, len, a));
            len = len<<1|1;
            /*for(int i = 0; i<len; i ++){
                printf("%d", a[i] - 1);
                printf(i == len-1 ? "
    " : " ");
            }*/
            sgt.build(1,0,len-1);
            int ans = 0;
            for (int i=2; i<len; i+=2) {
                int d = a[i]-1;
                int res = sgt.ask(1,0,len-1,i,i+d/2,i);
                //printf ("i=%d,(%d,%d)=%d
    ", i, i, i+d/2, res);
                res = (res-i)>>1;
                ans = max(ans, res*4);
            }
            printf ("%d
    ", ans);
        }
        return 0;
    }
    /*
    5
    aaaa
    aa
    abaabab
    abrahellehhelleh
    rachelhellabracadabra
    */
    Manacher
    #include<bits/stdc++.h>
    typedef long long ll;
    inline int clz(int x){return __builtin_clz(x);}
    inline int clz(ll x){return __builtin_clzll(x);}
    inline int lg2(int x){return !x ? -1 : 31-clz(x);}
    inline int lg2(ll x){return !x ? -1 : 63-clz(x);}
    using namespace std;
    const int M = 200000+10, mod = (int)1e9+7;
    int rk[M], sa[M], h[M], st[20][M];
    int n, m;
    char s[M];
    char t[M];
    int dp[M][32];
    int x;
    
    void da (char *s,int n,int m) {
        static int t1[M], t2[M], c[M];
        int *x=t1, *y=t2, i,j,k,p=1;
        memset (c, 0, sizeof(c[0])*m);
        for (i=0; i<n; i++) c[x[i]=s[i]] ++;
        for (i=1; i<m; i++) c[i] += c[i-1];
        for (i=n-1; i>=0; i--) sa[--c[x[i]]] = i;
        for (k=1; p<n; k<<=1, m=p) {
            for (p=0, i=n-k; i<n; i++) y[p++] = i;
            for (i=0; i<n; i++) if (sa[i]>=k) y[p++] = sa[i]-k;
            memset (c, 0, sizeof(c[0])*m);
            for (i=0; i<n; i++) c[x[i]]++;
            for (i=1; i<m; i++) c[i] += c[i-1];
            for (i=n-1; i>=0; i--) sa[--c[x[y[i]]]] = y[i];
            for (swap(x,y), x[sa[0]]=0, p=i=1; i<n; i++)
                x[sa[i]] = y[sa[i]] == y[sa[i-1]] &&
                    y[sa[i]+k] == y[sa[i-1]+k] ? p-1 : p++;
        }
        memcpy (rk, x, sizeof(x[0])*n);
        for (i=0, k=0; i<n-1; h[rk[i++]] = k?k--:k)
            for (j=sa[rk[i]-1]; s[i+k] == s[j+k]; k++);
        memcpy (st[0], h, sizeof(h[0])*n);
        for (k=1; 1<<k<=n; k++)
            for (i=0; i+(1<<k)-1<n; i++)
                st[k][i] = min (st[k-1][i], st[k-1][i+(1<<k-1)]);
    }
    
    int getlcp (int i,int j) {
        i = rk[i], j=rk[j];
        if (i>j) swap(i, j);
        i ++;
        int f = lg2 (j-i+1);
        return min (st[f][i], st[f][j-(1<<f)+1]);
    }
    
    int main () {
        scanf ("%d%s", &n, s);
        scanf ("%d%s", &m, t);
        scanf ("%d", &x);
        s[n] = '#';
        s[n+1] = 0;
        strcat (s, t);
        da (s, n+m+2, 128);
        memset (dp, -1, sizeof(dp));
        dp[0][0] = 0;
        for (int i=0; i<=n; ++i) {
            for (int j=0; j<=x; ++j) if (dp[i][j]!=-1) {
                dp[i+1][j] = max(dp[i+1][j], dp[i][j]);
                int lcp = getlcp (i, n+dp[i][j]+1);
                if (lcp == 0) continue;
                dp[i+lcp][j+1] = max(dp[i+lcp][j+1], dp[i][j] + lcp);
            }
        }
        for (int j=0; j<=x; ++j) {
            if (dp[n][j] == m) {
                puts ("YES");
                return 0;
            }
        }
        puts ("NO");
        return 0;
    }
    sa
  • 相关阅读:
    iOS应用崩溃日志分析
    iOS应用崩溃日志分析
    iOS 获取一个类的所有方法
    iOS 获取一个类的所有方法
    UVa 818Cutting Chains (暴力dfs+位运算+二进制法)
    UVa 1374 Power Calculus (IDA*或都打表)
    UVa 10603 Fill (暴力BFS+优先队列)
    HDU 1272 小希的迷宫 (并查集)
    HDU 1060 Leftmost Digit (数学log)
    UVa 1599 Ideal Path (两次BFS)
  • 原文地址:https://www.cnblogs.com/get-an-AC-everyday/p/7258422.html
Copyright © 2011-2022 走看看