1. 程式人生 > >2014多校聯合-第五場

2014多校聯合-第五場

1001:Inversion

模版題,求逆序數對。有多少逆序數對,就可以剪掉多少。

1003:Least common multiple

對於每一個子集,lcm為2的a的最大值次方*3的b的最大值次方。

所以我們只需要求出以某個b為b的最大值的時候,a的最大值的分佈情況即可。

我們先把b從小到大排序。

對於某一個b,我門只需要求出之前出現過的a比當前a小的數量為x;

那麼就可知對於這些a的子集,為2^x個,並且,每個子集a的最大值都為當前a。

我麼還需要求出對於大於當前a的a有多少個比a小的數,我們可以用線段樹逐步維護。

#include <iostream>
#include<stdio.h>
#include<vector>
#include<queue>
#include<stack>
#include<string.h>
#include<algorithm>
#include<math.h>
#include<map>
using namespace std;
#define LL long long
#define lcm(a,b) (a*b/gcd(a,b))
#define maxn 110000
#define lson l,(l+r)/2,rt<<1
#define rson (l+r)/2+1,r,rt<<1|1
struct list
{
    int a,b;
    friend bool operator <(const list &a,const list &b)
    {
        return a.b<b.b;
    }
}p[maxn];
int cmp(list a,list b)
{
    return a.a<b.a;
}
int ed[maxn];
LL num[maxn<<2];
LL sum[maxn<<2];
LL lazy[maxn<<2];
void push_down(int rt)
{
    if(lazy[rt]!=1)
    {
        sum[rt<<1]*=lazy[rt];
        sum[rt<<1|1]*=lazy[rt];
        sum[rt<<1]%=mod;
        sum[rt<<1|1]%=mod;
        lazy[rt<<1]*=lazy[rt];
        lazy[rt<<1|1]*=lazy[rt];
        lazy[rt<<1]%=mod;
        lazy[rt<<1|1]%=mod;
        lazy[rt]=1;
    }
}
void push_up(int rt)
{
    sum[rt]=sum[rt<<1]+sum[rt<<1|1];
    num[rt]=num[rt<<1]+num[rt<<1|1];
    sum[rt]%=mod;
}
void creat(int l,int r,int rt)
{
    num[rt]=sum[rt]=0;
    lazy[rt]=1;
    if(l!=r)
    {
        creat(lson);
        creat(rson);
        return;
    }
}
void insert(int x,int l,int r,int rt)
{
    if(x<l||x>r)return;
    if(l==r&&l==x)
    {
        num[rt]++;
        sum[rt]=M.q_mod(2,ed[x],mod);
        sum[rt]=(sum[rt]*lazy[rt])%mod;
        return;
    }
    push_down(rt);
    insert(x,lson);
    insert(x,rson);
    push_up(rt);
}
void updata(int ll,int rr,int l,int r,int rt)
{
    if(ll>rr)return ;
    if(ll>r||rr<l)return;
    if(ll<=l&&rr>=r)
    {
        lazy[rt]*=2;
        sum[rt]=sum[rt]*2%mod;
        return;
    }
    push_down(rt);
    updata(ll,rr,lson);
    updata(ll,rr,rson);
    push_up(rt);
}
LL query(int ll,int rr,int leap,int l,int r,int rt)
{
    if(ll>rr)return 0;
    if(ll>r||rr<l)return 0;
    if(ll<=l&&rr>=r)
    {
        if(leap==0)return num[rt];
        else return sum[rt];
    }
    push_down(rt);
    return query(ll,rr,leap,lson)+query(ll,rr,leap,rson);
}
int main()
{
    int n;
    while(~scanf("%d",&n))
    {
        for(int i=1;i<=n;i++)
        {
            scanf("%d%d",&p[i].a,&p[i].b);
        }
        sort(p+1,p+n+1,cmp);
        for(int i=1;i<=n;i++)
        {
            ed[i]=p[i].a;
            p[i].a=i;
        }
        creat(1,n,1);
        sort(p+1,p+n+1);
        LL sum=0;
        for(int i=1;i<=n;i++)
        {
            int k=p[i].a;
            LL x=query(1,k-1,0,1,n,1);
            LL y=query(k+1,n,1,1,n,1);
            LL now=M.q_mod(3,p[i].b,mod);
            LL ps=((M.q_mod(2,ed[k],mod))*(M.q_mod(2,x,mod)))%mod;
            sum+=now*((ps+y)%mod)%mod;
            insert(k,1,n,1);
            updata(k+1,n,1,n,1);
            sum=sum%mod;
        }
        cout<<sum<<endl;
    }
    return 0;
}



1005:Parenthese sequence

我的做法好像不是正經做法。。。sad

首先對於每一個)進行匹配(,如果匹配不到(,就匹配最前面的?,如果無法匹配,那就肯定無解。

一遍匹配之後,還剩下(還有?。

把每一個剩下的(匹配最後面的?;如果匹配不到?,肯定無解。

假如現在剩下x個?;

如果x是奇數,肯定無解。

如果x為0,肯定唯一解。

如果x>2,肯定多解。

如果x=2,那就把第一個?置為),第二個?置為(,如果可信,那就多解,否則,唯一解。

#include <iostream>
#include<stdio.h>
#include<vector>
#include<queue>
#include<stack>
#include<string.h>
#include<algorithm>
#include<map>
using namespace std;
#define LL long long
#define gcd(a,b) (b==0?a:gcd(b,a%b))
#define lcm(a,b) (a*b/gcd(a,b))
int pre[1100000];
int next[1100000];
char str[1100000];
stack<int>st;
stack<int>we;
int biao[1100000];
int fbiao[1100000];
int main()
{
    while(~scanf("%s",str))
    {
        while(!st.empty())st.pop();
        while(!we.empty())we.pop();
        memset(pre,-1,sizeof(pre));
        memset(next,-1,sizeof(next));
        int len=strlen(str);
        int last=-1;
        int leap=0;
        int sts=-1;
        for(int i=0;i<len;i++)
        {
            if(str[i]=='(')
            {
                st.push(i);
            }
            else if(str[i]==')')
            {
                if(st.empty())
                {
                    leap=1;
                    if(sts==-1)
                    {
                        leap=-1;
                        break;
                    }
                    else
                    {
                        str[sts]='(';
                        sts=next[sts];
                        if(sts==-1)
                        {
                            pre[sts]=-1;
                            sts=last=-1;
                        }
                        else pre[sts]=-1;
                    }
                }
                else
                {
                    int x=st.top();
                    st.pop();
                }
            }
            else if(str[i]=='?')
            {
                pre[i]=last;
                if(sts==-1)sts=i;
                else next[last]=i;
                last=i;
               // cout<<sts<<endl;
            }
        }
        if(leap==-1)
        {
            cout<<"None"<<endl;
            continue;
        }
        while(!st.empty())
        {
            if(last==-1)
            {
                break;
            }
            int x=st.top();
            if(x<last)
            {
                st.pop();
                str[last]=')';
                last=pre[last];
            }
            else break;
        }
        int ss=0;
        while(last!=-1)
        {
            last=pre[last];
            ss++;
        }
       // cout<<ss<<endl;
        if(leap==-1||!st.empty()||ss%2)
        {
            cout<<"None"<<endl;
            continue;
        }
        if(ss>2)
        {
            cout<<"Many"<<endl;
            continue;
        }
        if(ss==0)
        {
            cout<<"Unique"<<endl;
            continue;
        }
        while(!st.empty())st.pop();
        int lp=0;
        leap=1;
       // cout<<str<<endl;
        for(int i=0;i<len;i++)
        {
            if(str[i]=='?')
            {
                if(lp==0)
                {
                    str[i]=')';
                    lp++;
                }
                else str[i]='(';
            }
        }
     //   cout<<str<<endl;
        int i;
        for(i=0;i<len;i++)
        {
            if(str[i]=='(')st.push(i);
            else if(str[i]==')')
            {
                if(st.empty())break;
                else st.pop();
            }
        }
        if(i<len)cout<<"Unique"<<endl;
        else cout<<"Many"<<endl;
    }
    return 0;
}

1009:Exclusive or

因為結果是一些數的異或和。

我們就可以列舉每一位為1時,是由哪些數異或得來的。

對於當前位,如果A,B異或結果為1,那麼A,B這兩個數的當前位一個為1,一個為0,共有兩種情況。

已知A+B=n。

那麼對於當前位之前的數的和可以求出x種情況,對於當前位之後的數的和可以求出有y種情況。

那麼總過有x*y*2種情況。

又因為A,B都是非0的,所以還需要減去0的情況。

又因為是大數。。。所以要用java,大數用C++太費勁了。。

import java.util.Scanner;
import java.math.*;

public class Main {
    public static void main(String[] args) {
        Scanner cin = new Scanner(System.in);
        BigInteger n,m,sum,zero,one,two,x,k,y,ta,tb,z;
        BigInteger bit[] = new BigInteger[3300];
        bit[0] = BigInteger.valueOf(1);
        int i;
        for(i = 1;i <= 3000;i ++)
            bit[i] = bit[i-1].multiply(BigInteger.valueOf(2));
        zero = BigInteger.valueOf(0);
        one = BigInteger.valueOf(1);
        two = BigInteger.valueOf(2);
        while(cin.hasNext())
        {
            n = cin.nextBigInteger();
            m = n;
            sum = BigInteger.valueOf(0);
            for(i = 1;;i ++)
            {
                n = m.subtract(bit[i-1]);
                if(n.compareTo(zero) == -1)
                    break;
                x=n.divide(bit[i]).add(one);
                k=n.mod(bit[i]);
                if(bit[i-1].subtract(one).compareTo(k) == -1)
                    ta = bit[i-1].subtract(one);
                else 
                    ta = k;
                if(zero.compareTo(k.subtract(bit[i-1]).add(one)) == 1)
                    tb = zero;
                else 
                    tb = k.subtract(bit[i-1]).add(one);
                y=ta.subtract(tb).add(one);
                sum = sum.add(x.multiply(y).multiply(two).multiply(bit[i-1]));
                z = m.divide(bit[i]);
                k = m.divide(bit[i-1]);
                z = z.multiply(two);
                if(k.compareTo(z) != 0)
                {
                    sum = sum.subtract(bit[i-1].multiply(two));
                }
            }
            System.out.println(sum);
        }

    }
}

1010:Matrix multiplication

瞎搞題,把所有的0都去掉,然後就可以了。。。

理論時間複雜度為800*800*800*(2/3)*(2/3)

#include <iostream>
#include<stdio.h>
#include<vector>
#include<queue>
#include<stack>
#include<string.h>
#include<algorithm>
#include<map>
using namespace std;
#define LL long long
#define gcd(a,b) (b==0?a:gcd(b,a%b))
#define lcm(a,b) (a*b/gcd(a,b))
//O(n)求素數,1-n的尤拉數
#define N 100010
//A^x = A^(x % Phi(C) + Phi(C)) (mod C)
int a[880][880];
int b[880][880];
int aa[880][880];
int bb[880][880];
int c[880][880];
int main()
{
    int n;
    while(~scanf("%d",&n))
    {
        memset(a,0,sizeof(a));
        memset(b,0,sizeof(b));
        memset(aa,0,sizeof(aa));
        memset(bb,0,sizeof(bb));
        memset(c,0,sizeof(c));
        for(int i=1;i<=n;i++)
        {
            for(int j=1;j<=n;j++)
            {
                scanf("%d",&a[i][j]);
                a[i][j]%=3;
            }
        }
        for(int i=1;i<=n;i++)
        {
            for(int j=1;j<=n;j++)
            {
                scanf("%d",&b[i][j]);
                b[i][j]%=3;
            }
        }
        for(int i=1;i<=n;i++)
        {
            int x=-1;
            for(int j=n;j>=0;j--)
            {
                aa[i][j]=x;
                if(a[i][j])x=j;
            }
        }
        for(int i=1;i<=n;i++)
        {
            int x=-1;
            for(int j=n;j>=0;j--)
            {
                bb[i][j]=x;
                if(b[i][j])x=j;
            }
        }
        for(int i=1;i<=n;i++)
        {
            for(int j=aa[i][0];j!=-1;j=aa[i][j])
            {
                for(int k=bb[j][0];k!=-1;k=bb[j][k])
                    c[i][k]+=a[i][j]*b[j][k];
            }
        }
        for(int i=1;i<=n;i++)
        {
            for(int j=1;j<=n;j++)
            {
                printf("%d",c[i][j]%3);
                if(j!=n)printf(" ");
                else printf("\n");
            }
        }
    }
    return 0;
}


相關推薦

2014聯合-

1001:Inversion 模版題,求逆序數對。有多少逆序數對,就可以剪掉多少。 1003:Least common multiple 對於每一個子集,lcm為2的a的最大值次方*3的b的最大值次方。 所以我們只需要求出以某個b為b的最大值的時候,a的最大值的分佈情況即可

2017聯合91010 Two String/hdu 6170(正則表示式/dp)

Two strings Time Limit: 2000/1000 MS (Java/Others)    Memory Limit: 65536/65536 K (Java/Others) Total Submission(s): 680    Accepted Su

2017聯合/HDU 6171 Admiral 雙向bfs + 雜湊

Suppose that you are an admiral of a famous naval troop. Our naval forces have got 21 battleships. There are 6 types of battleships. First, we have got on

hdu 4911 Inversion(歸併排序求逆序對數)2014訓練5

Inversion                                                                             Time Limit: 2000/1000 MS (Java/Others)    Memory L

HDU 6350 2018HDU Always Online(圖論 + 並查集 + 組合計數)

          大致題意:給你一個仙人掌圖,讓你計算:。 根據去年多校賽某一道題的經驗,很多仙人掌圖的問題,其實可以轉化為樹的問題。所以我們同樣考慮,如果這是一棵樹的話如何去做。注意到表示式裡面的flow(i,j)表示從i到j的最小割或最大流,而在樹上的最小

聯合

1003 The Goddess Of The Moon 題意:如果字串存在某個字首與另一個字串的字尾相同,則這兩個字串匹配,求n種字串連成m個字串的連線方式。 dp[i][j]=∑<k,j>匹配dp[i−1][k],dp[i][j]是指前i個串

2017聯合/hdu 6136Death Podracing(優先佇列+迴圈連結串列)

> During the Trade Federation invasion of Naboo, Anakin Skywalker won the Boonta Eve Classic on Tatooine, securing his freedom from a life of slavery.

HDU6395 Sequence 2018聯合 代常數矩陣快速冪+分段思維

這道題emmmmmmn... 比賽的時候想到矩陣快速冪了,但分段這個真的是...不好想更不好敲。。後來看了標程,豁然開朗Orz 只能說明。。我好菜啊啊啊啊啊555555... 遞推式如下:(x是不斷更新的量)                           |  

HDU 4864 Task (2014聯合訓練第一1004) 解題報告(貪心)

Task Time Limit: 4000/2000 MS (Java/Others)    Memory Limit: 32768/32768 K (Java/Others) Total Submission(s): 400    Accepted Submission(

牛客網訓練營gpa(01分數規劃)

01分數規劃 01分數規劃問題:所謂的01分數規劃問題就是指這樣的一類問題,給定兩個陣列,a[i]表示選取i的收益,b[i]表示選取i的代價。如果選取i,定義x[i]=1否則x[i]=0。每一個物品只有選或者不選兩種方案,求一個選擇方案使得R=sigma(a[i]*x[

hdu 4865 Peter's Hobby(2014 聯合第一 E)

Recently, Peter likes to measure the humidity of leaves. He recorded a leaf humidity every day. There are four types of leaves wetness: Dry , Dryish , Dam

HDU 5399 Too Simple (2015年比賽9

assert vector math php post long long size 答案 ring 1.題目描寫敘述:點擊打開鏈接 2.解題思路:本題分情況討論。比賽時候真是想的太簡單了。以為就是(n!)^(cnt-1)。終於無限WA。本題有幾個特殊情況須要額外推斷。

HDU9 HDU 4965Fast Matrix Calculation【矩陣運算+數學小知識】

stdin amp line you stream [] nbsp content ans 難度上。,,確實。。。不算難 問題是有個矩陣運算的優化 題目是說給個N*K的矩陣A給個K*N的矩陣B(1<=N<=1000 && 1=<K<

【補題】聯合訓練第一

microsoft range else result tdi ask lis positive -1 1001 Add More Zero Problem Description There is a youngster known for amateur pro

【補題】聯合訓練第二

num isf scan logs n-2 urn open interval names 第二場 1001 Is Derek lying? Problem Description Derek and Alfia are good friends.Derek is Chin

HDU 5411 CRB and Puzzle (2015年比賽10

理解 tor for truct rac iostream blank 全部 sta 1.題目描寫敘述:pid=5411">點擊打開鏈接 2.解題思路:本題實際是是已知一張無向圖。問長度小於等於m的路徑一共同擁有多少條。能夠通過建立轉移矩陣利用矩陣高速冪解決。當中

牛客網訓練 C - Shuffle Cards(Splay / rope)

str spl shuf 鏈接 contest www size targe strong 鏈接: https://www.nowcoder.com/acm/contest/141/C 題意: 牛客網多校訓練第三場 C - Shuffle Cards(Splay /

2018航電練習9-快速冪

pos rac pre height 快速冪 都沒有 mit limit 需要 Rikka with Badminton Time Limit: 2000/1000 MS (Java/Others) Memory Limit: 524288/524288 K (Jav

HDU 6338 2018HDU Depth-First Search(組合數學+平衡樹/pbds)

大致題意:給你一個dfs序列B和一棵樹,現在讓你在這個樹上隨機選擇一個點,然後按照隨機的dfs順序走。問你最後能走出幾個dfs序列,是得該dfs序列字典序小於給定的dfs序B。 首先,我們考慮一棵樹有根樹他的dfs序有多少種。我們可以這麼考慮,對於任意點x,

2017年 1005 FFF at Valentine(縮點+拓撲排序)

其實縮點很容易想到,就是不怎麼會用拓撲排序所以一直卡著判斷這個地方。 程式碼如下: #include <stdio.h> #include <string.h> #include <vector> #include <s