1. 程式人生 > >2018.8.25 練習賽

2018.8.25 練習賽

好的 dmi 特殊 png 處理 clu 進行 分享 include

  • T1 試卷
  • 題面:

試卷(paper .cpp/.in/.out) 1s 512MB

題目描述

THH為了回答SF之間,決定在之後的m天中刷很多理綜卷子,於是他收集到了 n套理綜試卷,每套試卷鄒是不同的。

為了體現概率的根本性,THH 決定隨機選擇一一個刷題方案,但是為了不讓自己某一天太過無聊,他要求每天至少要刷一套試卷,同時為了不讓自己過度勞累,他決定這n套題不需要全部刷完。THH當然想知道,總共有多少種可能的刷題方案。

THH當然知道答案,但是他希望你幫他驗證一下,由於THH可能會刷很多題,所以你只需要算出答案對p取技術分享圖片

模後的結果就行了。

輸入格式

第一行三個整數id,T,p,分別表示測試點編號,數據組數,模數

接下來T行,每行三個整數n,m,表示一組數據

輸出格式

輸出T行,每行一個整數ans,分別表示每組數據的答案對p取模的結果

樣例輸入1

998244353

76

2464 22902603 421

2603 421

樣例輸出1

1
7
213358738
919699705

數據範圍

本題采用打包測試,你只有通過一一個子任務的所有測試點才能獲得該子任務對應的分數

對於所有數據,保證m≤n,1≤id≤7

子任務1 (20分):T≤10^5,n≤5000, m<= 5000,p = 998244353, id= 1

子任務2(25分):T≤10^5,n≤10^7,m≤10^7 ,p= 998244353, id= 2

子任務3(15分):T≤10^5,n≤10^15,m≤10^15,p=19999,id= 3

子任務4(15分):T≤3x10^6,n≤10^7,m≤10^7,p=3,id= 4

子任務5(10分):T≤10,n≤10^5,m≤10^15,p= 877368967,id= 5

子任務6(5分) :T≤2x10^3,n≤10^5,m≤10^l5,p= 536078816,id= 6

子任務7(10分):T=30,n≤10^9,m≤10^9,p= 100000007, id= 7

  • 名副其實的毒瘤題,七個子任務使用不同的解法:
  • 1、暴力O(n^2)即可
  • 2、線性求逆元+預處理階乘
  • 3、Lucas
  • 4、計算階乘時將3的倍數提出,然後暴力計算
  • 5、CRT
  • 6、擴展Lucas
  • 7、打表,預處理k,2*k……然後用最近的階乘進行計算
  • code待補

  • T2 果實
  • 題面:

果實(fruit.cpp/.in/.out) 1s 32MB

題日描述

THH解決了SF之間後決定大宴賓客,於是他找到了一棵有n個節點的果樹,這棵果樹上總共有C種不同的果k,樹上每個節點都 有一一顆果實。

現在THH為了表明自己很文明,決定只在果樹上選擇一-棵子樹摘走,同時,他希望摘到盡可能多的種類的果實,現在THH希望 你能幫助他確定某些子樹中總共有多少種不同的果實。

THH總共會有m次詢問,為了方便,THH指定了根為1號節點。

輸入格式

第一行三個整數n,m,C,意義如題所述

第二行n個整數ay,表示每個節點上果實的種類

接下來n-1行,每行兩個整數cy,表示果樹上的一一條邊

接下來m行,每行一個整數p,表示THH詢問以p為根的子樹中總共有多少種不同的果實

輸出格式

輸出m行,每行一個整數ans,表示每個詢問的答案

樣例輸入1

6 3 5
1 2 3 4 5 1
5 1
1 3
3 4
4 2
3 6
1
4
6

樣例輸出1

5
2
1

數據範圍

本題采用打包測試,你只有通過一一個子任務的所有測試點才能獲得該子任務對應的分數

對於所有數據,保證n,m,C≤10^5,1≤a;≤C

予任務1(20分) :n≤5000,m≤5000,C≤105

子任務2(30分):n≤10^5,m≤10^5,C≤60

子任務3(10分):n≤10^5,m≤10^5,C≤10^5,保證樹的形態為一條鏈

子任務4(40分):n≤5x10^5,m≤5x10^5,C≤5x10^5

  • 正解是dfs序將子樹問題轉化為區間問題樹狀數組維護樹上查分;但是用莫隊莫名其妙就玄學卡過了……
  • 莫隊代碼:
  • 技術分享圖片
     1 #include<stdio.h>
     2 #include<math.h>
     3 #include<ctype.h>
     4 #include<vector>
     5 #include<algorithm>
     6 using namespace std;
     7 
     8 char buf[1<<20],*p1,*p2;
     9 inline char gc() {
    10     return p1==p2&&(p2=(p1=buf)+fread(buf,1,1<<20,stdin))==p1?0:*p1++;
    11 }
    12 
    13 template<typename T>
    14 void read(T &x) {
    15     char tt;
    16     bool flag=0;
    17     while(!isdigit(tt=gc())&&tt!=-);
    18     tt==-?(x=0,flag=1):(x=tt-0);
    19     while(isdigit(tt=gc())) x=x*10+tt-0;
    20     if(flag) x=-x;
    21 }
    22 
    23 template<typename T>
    24 void write(T x,bool flag)
    25 {
    26     if(x<0) putchar(-),x=-x;
    27     if(!flag) putchar(x%10+0);
    28     if(x>9) write(x/10),putchar(x%10+0);
    29 }
    30 
    31 struct node {
    32     int l,r,id;
    33 } q[500005];
    34 
    35 int n,m,c;
    36 vector<int>G[500005];
    37 int dfn[500005],pos[500005][2],tot;
    38 int tmp[500005],block[500005],s,Ans,l=1,r;
    39 int d[500005];
    40 int a[500005],ans[500005];
    41 
    42 bool cmp(node a,node b) {
    43     return block[a.l]==block[b.l]?a.r<b.r:a.l<b.l;
    44 }
    45 
    46 void modify(int x,int k) {
    47     d[x]+=k;
    48     if(k>0) Ans+=d[x]==1;
    49     if(k<0) Ans-=d[x]==0;
    50 }
    51 
    52 void dfs(int x,int pre) {
    53     dfn[++tot]=x;
    54     pos[x][0]=tot;
    55     for(int i=0,p=G[x][i]; i<G[x].size(); i++,p=G[x][i])
    56         if(p!=pre) dfs(p,x);
    57     pos[x][1]=tot;
    58 }
    59 
    60 int main() {
    61     scanf("%d%d%d",&n,&m,&c);
    62     for(int i=1; i<=n; i++) scanf("%d",&tmp[i]);
    63     for(int i=1; i<n; i++) {
    64         int x,y;
    65         scanf("%d%d",&x,&y);
    66         G[x].push_back(y);
    67         G[y].push_back(x);
    68     }
    69     dfs(1,0);
    70     s=pow(tot,0.6666);
    71     for(int i=1; i<=m; i++) {
    72         int x;
    73         scanf("%d",&x);
    74         q[i]=(node) {
    75             pos[x][0],pos[x][1],i
    76         };
    77         block[i]=(i-1)/s+1;
    78     }
    79     for(int i=1; i<=n; i++) a[i]=tmp[dfn[i]];
    80     sort(q+1,q+1+m,cmp);
    81     for(int i=1; i<=m; i++) {
    82         while(l<q[i].l) modify(a[l],-1),l++;
    83         while(l>q[i].l) modify(a[l-1],1),l--;
    84         while(r<q[i].r) modify(a[r+1],1),r++;
    85         while(r>q[i].r) modify(a[r],-1),r--;
    86 
    87         ans[q[i].id]=Ans;
    88     }
    89     for(int i=1; i<=m; i++)
    90         printf("%d\n",ans[i]);
    91 }
    View Code

  • T3 旅行
  • 題面:

旅行(travel.cpp/.in/.out) 1s 32MB

題目描述

心情大好的THH決定出去旅行,他決定在n個城市中米選擇旅行路線,這n個城市由m條雙向道路連接,由於特殊的原因,對於 雙向道路(r,y),→y的長度為c,y→x的長度為di,THH居住的城市為1號城市。
現在THH想要從1號城市出發,經過一些城市,最後回到1號城市,並且由於每條路上的風景是一樣的,因此THH要求每條邊至 多經過一次,然而TH H發現旅行可能會耗費過多時間,於是他決定在所有的可能路線中選擇最短的那一. 條路線。
由於THH正忙於收拾書包,所以他拜托你幫他計算一-下最短的可能路線的長度。
輸入格式
第一行兩個整數n,m,意義如題所述
接下來m行,每行三個整數正, Yi,Gi,d;,表示一條道路

輸出格式

輸出一行,一個整數ans,表示答案

樣例輸入1

5 7
1 2 3 2
1 3 3 3
2 4 1 2
2 5 7 8
4 5 2 2
3 5 3 4
3 4 8 7

樣例輸出1

12

數據範圍

本題采用打包測試,你只有通過一一個子任務的所有測試點才能獲得該子任務對應的分數
對於所有數據,保證n≤5x 10^4,m≤5x 10^5,0≤d;≤10^4,保證圖中不存在重邊和自環,保證一定有解
子任務1 (20分):n≤20,m≤100
子任務2(30分) :n≤1500,m < 15000
子任務3(50分):n≤5x 10^5,m≤2x10^5

  • 正解為迪傑斯特拉,將一號點分為兩組,一組只有出,一組只有入,隨機化跑30次,錯誤幾率為(3/4)^30
  • code待補


2018.8.25 練習賽