1. 程式人生 > >ZOJ Monthly, January 2018 總結。

ZOJ Monthly, January 2018 總結。

刷了一下也沒有時間補題,看了別人的題解,就總結一下:

A:水題。

B:

給定n字串,每次詢問查詢兩個字串的一個公共字尾,使得這個公共字尾在n個字串中至少有一個字串S,使得這個公共字尾是S的字首。問滿足條件的最長公共字尾 F,這個字尾F是一個字串的字首的話就++num。輸出num.

題解:

對所有串建立AC自動機,那麼若字首i是字首jj的字尾,說明ii是Fail樹上j的祖先。

所以對於詢問(x,y),答案就是兩點在Fail樹上的LCA在原Trie中子樹內的字串總數。

時間複雜度O(nlogn)。

還有暴力點的題解:求出最長公共字尾,然後列舉字尾 字典樹求ans.

總結:遇到這種字首與字尾相同就應該想到fail指標。

D:

題意:給m個位置,10種人,1,2,3,4,,10第i種人只做 編號為i的倍數的位置,給出每種人的數量,求能安排的最多人數。

lcm(1,2,...,10)=2520,對於模lcm的每個餘數k分析其是否是1到10的倍數,可以發現一共48種本質不同的情況。

那麼計算出每種情況的容量之後,就轉化成了左邊10個點,右邊48個點的最大流。

總結:可以理解為匹配問題,用lcm(週期)來減少點,然後有一些點可以看成相同的,再次減少點,對於相同型別的點可以合併然後加cap就能減少點,減少複雜度。

J:

給定兩個數列a,b,分別在兩個數列上選取相同長度的連續的子序列,使得兩個子序列中Σ(abs(a[i]-b[j])^p)<=v,問有多少種選取方案

暴力:把兩個數列想象成二維陣列:每個對角線就是 對應 連續的子序列,然後對對角線掃一遍。

#include<iostream>
#include<stdio.h>
#include<algorithm>
#include<string.h>
using namespace std;
typedef long long int ll;
const int maxn = 1000;
int n,p,a[maxn+5],b[maxn+5];
ll g[maxn*maxn+5],V,w[maxn*maxn+5],ans;
ll pows(ll x,int p)
{
    ll r = 1;
    for(int i=1; i<=p; i++) r*=x;
    return r;
}
int main()
{
    int T;
    scanf("%d",&T);
    while(T--)
    {
        scanf("%d %lld %d",&n,&V,&p);
        for(int i=1; i<=n; i++) scanf("%d",&a[i]);
        for(int i=1; i<=n; i++) scanf("%d",&b[i]);
        ans = 0;
        for(int i=1; i<=n; i++)
        {
            int x = i, y = 1, len = 0, l = 1,j=1;
            ll sum = 0;
            while(x<=n&&y<=n)
            {
                w[++len] = pows(abs(a[x]-b[y]),p);
                sum+=w[j];
                while(sum>V&&l<=j) sum-=w[l++];
                ans+=j-l+1;
                x++,y++,j++;
            }
        }
        for(int i=2; i<=n; i++)
        {
            int x = 1, y = i, len = 0, l = 1,j=1;
            ll sum = 0;
            while(x<=n&&y<=n)
            {
                w[++len] = pows(abs(a[x]-b[y]),p);
                sum+=w[j];
                while(sum>V&&l<=j) sum-=w[l++];
                ans+=j-l+1;
                x++,y++,j++;
            }
        }
        printf("%lld\n",ans);
    }
    return 0;
}