Test on 11/4/2018

来浙理的第一次月赛,嗯我是被大佬吊着打的垃圾。

A:优美数

Description

如果一个数中只有少于三个数字是非零的,那么我们称这个数为优美数,我们定义这个优美数的优美程度为这个数所有数字相加的和。 例如优美数有4,200000,10203,其中4的优美度是4,200000的优美度是2,10203的优美度是6. 数字4231,102306,7277420000,就不是啰。

现在问在【L,R】中,有多少个优美度为x的优美数。

Input

T组数据,T<=5e4. 第一行为组数T。 接下来T行,每组输入L,R,x。1<=L <= R <= 3e18;

Output

每行输出一个对应的答案

Examples

Input

4

1 1000 1

1024 1024 7

65536 65536 15

1 1000000000 20

Output

4

1

0

3024

 

正确解法:

先dfs,预处理所有的情况,然后对每次询问进行二分求解。

也可用数位DP。

  1 #include <algorithm>
  2 #include  <iterator>
  3 #include  <iostream>
  4 #include   <cstring>
  5 #include   <cstdlib>
  6 #include   <iomanip>
  7 #include    <bitset>
  8 #include    <cctype>
  9 #include    <cstdio>
 10 #include    <string>
 11 #include    <vector>
 12 #include     <stack>
 13 #include     <cmath>
 14 #include     <queue>
 15 #include      <list>
 16 #include       <map>
 17 #include       <set>
 18 #include   <cassert>
 19 using namespace std;
 20  
 21  
 22 typedef long long ll;
 23  
 24             const int maxn = 3e6+9;
 25             int tot = 0;
 26             vector<ll>mp[30];
 27             int cnt(ll x){
 28                 int res = 0;
 29                 while(x>0){
 30                     res += x%10;
 31                     x/=10;
 32                 }
 33                 return res;
 34             }
 35             set<int>sss;
 36             void dfs(ll x,int cur,int num){
 37                 if(cur>19||num > 3)return;
 38  
 39                 if(num<=3){
 40                     int tmp = cnt(x);
 41                     mp[tmp].pb(x);
 42                     // tot++;
 43                     sss.insert(tmp);
 44                     // if(cnt(x) == 50)cout<<x<<endl;
 45                 }
 46                 for(int i=0;i<=9; i++){
 47                     if(i==0)dfs(x*10ll, cur+1,num);
 48                     else dfs(x*10ll + i, cur+1,num+1);
 49                 }
 50             }
 51             int find1(ll x,int id){
 52                 int le = 0,ri = mp[id].size() - 1;
 53                 int res = ri+1;
 54                 while(le <= ri){
 55                     int mid = (le + ri)>>1;
 56                     
 57                     if(mp[id][mid] < x){
 58                         le = mid+1;
 59                     }
 60                     else{
 61                         res = mid; ri = mid - 1;
 62                     }
 63                 }
 64  
 65                 return res;
 66             }
 67              int find2(ll x,int id){
 68                 int le = 0,ri = mp[id].size() - 1;
 69                 int res = 0;
 70                 while(le <= ri){
 71                     int mid = (le + ri)>>1;
 72                     if(mp[id][mid] > x){
 73                         ri = mid - 1;
 74                     }
 75                     else {
 76                         res = mid;
 77                         le = mid + 1;
 78                     }
 79                 }
 80                 return res;
 81             }
 82 int main(){
 83  
 84             // freopen("data.in","r", stdin);
 85             // freopen("output.out","w",stdout);
 86             for(int i=1; i<=9; i++)dfs(i,1,1);
 87             //tot = 720423
 88     
 89             for(int k : sss){//27次
 90                 sort(mp[k].begin(),mp[k].end());
 91             }
 92  
 93             int t;scanf("%d", &t);
 94             while(t--){
 95                 ll l,r;int x;
 96                 scanf("%lld%lld%d", &l, &r, &x);
 97                 if(x >= 28){
 98                     puts("0");
 99                 }
100                 else if(l<r){
101                         int t1 = find1(l,x);
102                         int t2 = find2(r,x);
103                         printf("%d
",t2 - t1 + 1);
104                 }
105                 else if(l==r){
106                         int t1 = lower_bound(mp[x].begin(),mp[x].end(),l) - mp[x].begin();
107                         if(t1<mp[x].size() && mp[x][t1] == l)puts("1");
108                         else puts("0");
109                 }
110             }
111            return 0;
112 }
View Code
 1 #include <algorithm>
 2 #include  <iterator>
 3 #include  <iostream>
 4 #include   <cstring>
 5 #include   <cstdlib>
 6 #include   <iomanip>
 7 #include    <bitset>
 8 #include    <cctype>
 9 #include    <cstdio>
10 #include    <string>
11 #include    <vector>
12 #include     <stack>
13 #include     <cmath>
14 #include     <queue>
15 #include      <list>
16 #include       <map>
17 #include       <set>
18 #include   <cassert>
19 using namespace std;
20 #define se second
21 #define fi first
22 #define ll long long
23 #define Pii pair<int,int>
24 #define Pli pair<ll,int>
25 #define ull unsigned long long
26 #define pb push_back
27 const int N=1e4+10;
28 const int INF=0x3f3f3f3f;
29 const int mod=1e9+7;
30 using namespace std;
31 int a[30];
32 ll dp[20][30][4][30];
33 int k;
34 ll dfs(int pos,int now,int num,bool limit){
35     if(num > 3) return 0;
36     if(pos==-1) return now == k;
37     if(!limit && dp[pos][now][num][k]!=-1) return dp[pos][now][num][k];
38     int up=limit?a[pos]:9;
39     ll ans=0;
40     for(int i=0;i<=up&&now+i<=k;++i){
41        ans+=dfs(pos-1,now+i,num+(i!=0),limit&&i==a[pos]);
42     }
43     if(!limit) dp[pos][now][num][k]=ans;
44     return ans;
45 }
46 ll solve(ll x){
47     int pos=0;
48     if(x==0)return 0;
49     while(x){
50         a[pos++]=x%10;
51         x/=10;
52     }
53     return dfs(pos-1,0,0,1);
54 }
55 int main(){
56 //    freopen("data1.in", "r", stdin);
57 //    freopen("ac.out", "w", stdout);
58     memset(dp,-1,sizeof(dp));
59  
60     int T;scanf("%d",&T);
61     while(T--){
62         ll l,r;
63         scanf("%I64d%I64d%d",&l,&r,&k);
64         if(k>27)printf("0
");
65         else printf("%I64d
",solve(r)-solve(l-1));
66     }
67  
68     return 0;
69 }
View Code

B:私人奶茶店

Description

C有一家奶茶店,其中有n种奶茶,每种奶茶都有a【i】个,小C每天都会等概率地从剩余的奶茶中选一杯奶茶喝掉,问小C第K天喝到第m种奶茶的概率是多少。

Input

第一行n,代表奶茶的种类数

第二行n个数,表示a【i】

第三行k,m,表示第k天喝到第m种奶茶的概率

n<=1e5, 0 < a[i] <= 1e6

1<=k<=sum(a[i]), 1<=m<=n)

Output

用最简分数表示。

Examples

Input

2

1 1

1 1

Output

1/2

正确解法:

a[m] / sum   与k无关,最后要gcd

 1 #include <cstdio>
 2 #include <iostream>
 3 using namespace std;
 4 typedef long long ll;
 5 const int maxn = 1e5+9;
 6 ll a[maxn];
 7 ll gcd(ll a, ll b){
 8     if(b==0)return a;
 9     return gcd(b, a%b);
10 }
11 int main(){ 
12         // freopen("data5.in", "r", stdin);
13         int n;scanf("%d", &n);
14         ll sum = 0;
15         for(int i=1; i<=n; i++)scanf("%lld", &a[i]),sum+=a[i];
16         cout<<"sum"<<sum<<endl;
17         int k,m;
18         scanf("%d%d", &k, &m);
19         ll g = gcd(sum,a[m]);
20         printf("%lld/%lld
", 1ll*a[m]/g, 1ll*sum/g);
21         return 0;
22 }
View Code

C:素数空间

Description

一天,小明正在搬砖,他收集了n(n<=1e7)种砖,砖的编号1-n这个时候,他突然说了一句,召唤神龙,然后,他穿越到了一个时空,发现这里的东西都是由素数组成的,这里的砖也和素数有关,他的砖也和他一块过来了,只是发生了一些变化,编号为1的砖不见了,编号为素数的砖没有发生变化,编号为合数的砖变成了编号为几块素数的砖(砖的编号和为之前的那个合数),由于这个世界能量太少,所以这些合数的砖尽可能的变成数目少的其他砖。于是小明想请教你他还有多少砖。例如 编号为12的砖会变成编号5 7 的砖  不会变成编号2 3 2 2 3 的砖     编号9的砖会变成编号2 7 的砖  不会变成编号 3 3 3  的砖

Input

给你一个T(1<=T<=3e3) 
接下来T行每行一个n(0<=n<=1e7)

Output

一共T行,每一行输出一个结果;

Examples

Input

2

3

5

Output

2

5

正确解法:

根据哥德巴赫猜想

大于二的偶数可以分解为两个素数之和

大于七的奇数可以分解为三个素数之和

(一定可以分解成三个素数之和,也有可能分解为两个,分解成两个其中必然有一个是2,其他就是至少三个)

1.先线性筛出所有的素数。

2.遍历1-le7里的素数、偶合数、奇合数

3.预处理一遍就行了

 1 #include<bits/stdc++.h>
 2 using namespace std;
 3 const int maxn=1e7+5;
 4 bool prime[maxn];
 5 int p[maxn];
 6 int tot;
 7 void findprime()
 8 {
 9     for(int i = 2; i < maxn; i ++)  prime[i] = true;
10     for(int i = 2; i < maxn; i ++)
11     {
12         if(prime[i])  p[++tot]=i;
13         for(int j=1;j<=tot && i*p[j]<maxn; j++)
14         {
15             prime[i*p[j]]=false;
16             if(i%p[j]== 0) break;
17         }
18     }
19 }
20 int  ans[maxn];
21 int main()
22 {
23    // freopen("g4.in","r",stdin);
24    // freopen("g4.out","w",stdout);
25     findprime();
26     for(int i=2;i<=maxn;i++)
27     {
28         if(prime[i]==1) ans[i]=ans[i-1]+1;
29         else
30         {
31             if(i%2==0) ans[i]=ans[i-1]+2;
32             else
33             {
34                 if(prime[i-2]==1) ans[i]=ans[i-1]+2;
35                 else              ans[i]=ans[i-1]+3;
36             }
37         }
38     }
39    int t;cin>>t;
40    while(t--)
41    {
42        int n; cin>>n; cout<<ans[n]<<endl;
43    }
44 }
View Code

D:摩天大楼

Description

随着科技的发展,某国家准备修建一座高楼,高度为n(n<=1e18),来展现他们国家的强大国力,他们国家有两支强大的施工队,国家于是把修建计划给了这两只施工队,为了提高施工队的积极性,国家会特殊奖励最后完成施工的,两只施工的施工计划是两只施工队轮流工作,由于施工队实力有限,每天只能修建1-m(m<=1e18)层,假如两只施工队都非常聪明,问首先施工的那只队伍能不能获得奖励,能输出YES,不能输出NO

Input

数据的组数 T;(T<=3000)     

接下来T行,每行一个n m, 楼的高度,最大修建层数   (n,m<=1e18)

Output

每行一个单独的YES或者NO;

Examples

Input

2

2 1

6 4

Output

NO

YES

正确解法:

两只队伍都非常聪明,知道如何使自己赢,每个人取的都是1~m个

无论第一支队伍取多少个,第二支队伍都能使两只队伍的和为1+m 个

故 n为m+1的倍数或者0时候,先手必输,其余先手必赢.

 1 #include<bits/stdc++.h>
 2 using namespace std;
 3 int main()
 4 {
 5    // freopen("cc.in","r",stdin);
 6   //  freopen("in.out","w",stdout);
 7     long long n,m;
 8     int t; cin>>t;
 9     while(t--)
10     {
11        cin>>n>>m;
12       if(n%(m+1)==0) cout<<"NO"<<endl;
13        else           cout<<"YES"<<endl;
14     }
15 }
View Code

E:招生

Description

 浙江理工大学招生,一开始有0名学生报考,现在有如下几种情况;

1.增加一名报考学生,报考学生成绩为x;

2.一名成绩为x的学生放弃报考。

3.从现在报考的学生来看,老师想知道如果要招生至少x名学生,需要将分数线最高设置为多少;

4.从现在报考的学生来看,如果分数线设置为x,能有几名学生被录取。

第一行先输入一个n,表示有n次操作或查询;

接下来n行,每行输入两个整数opt和x(用空格隔开):

如果opt为1,则增加一名报考学生,报考学生成绩为x;

如果opt为2,则表示一名成绩为x的学生放弃报考。

如果opt为3,从现在报考的学生来看,老师想知道如果要招生至少x名学生,需要将分数线最高设置为多少,输出最高分数线。

如果opt为4,从现在报考的学生来看,如果分数线设置为x,能有几名学生被录取,输出录取人数。

对于每个输出占一行。

n不超过50000;0<=x<=1000000;1<=k<=现在的学生数。

Input

第一行输入一个n,接下来n行,每行输出两个整数opt,x,用空格隔开

Output

对于每次输出, 输出一个整数占一行

Examples

Input

18

1 3

1 4

1 5

1 6

1 7

1 8

1 9

1 10

1 11

1 12

2 8

3 2

3 3

3 4

3 5

4 8

4 9

4 7

Output

11

10

9

7

4

4

5

正确解法:

平衡树treap

  1 #include<bits/stdc++.h>
  2 #define fi first
  3 #define se second
  4 #define INF 0x3f3f3f3f
  5 #define fio ios::sync_with_stdio(false);cin.tie(0);cout.tie(0)
  6 #define pqueue priority_queue
  7 #define NEW(a,b) memset(a,b,sizeof(a))
  8 const double pi=4.0*atan(1.0);
  9 const double e=exp(1.0);
 10 const int maxn=1e6+8;
 11 typedef long long LL;
 12 typedef unsigned long long ULL;
 13 //typedef pair<LL,LL> P;
 14 const LL mod=1e9+7;
 15 const ULL base=1e7+7;
 16 using namespace std;
 17 struct node{
 18     int son[2];
 19     int siz;
 20     int key,w;
 21 }a[maxn];
 22 int tot=0;
 23 int root=0,vis[maxn];
 24 void up(int i){
 25     a[i].siz=a[a[i].son[0]].siz+a[a[i].son[1]].siz+1;
 26 }
 27 void Rotate(int &i,int d){
 28     int t=a[i].son[d];
 29     a[i].son[d]=a[t].son[!d];
 30     a[t].son[!d]=i;
 31     up(i);up(t);
 32     i=t;
 33 }
 34 void Insert(int &i,int key){
 35     if(i==0){
 36         i=++tot;
 37         a[i].siz=1;a[i].key=key;a[i].w=rand();
 38         return ;
 39     }
 40     a[i].siz++;
 41     if(a[i].key>=key) {
 42         Insert(a[i].son[0],key);
 43         if(a[a[i].son[0]].w<a[i].w) Rotate(i,0);
 44     }
 45     else{
 46         Insert(a[i].son[1],key);
 47         if(a[a[i].son[1]].w<a[i].w) Rotate(i,1);
 48     }
 49 }
 50 void Del(int &i,int key){
 51     if(a[i].key==key){
 52         if(a[i].son[0]*a[i].son[1]==0)  {i=a[i].son[0]+a[i].son[1];return ;}
 53         if(a[a[i].son[0]].w>a[a[i].son[1]].w){
 54             Rotate(i,1);
 55             Del(a[i].son[0],key);
 56         }
 57         else{
 58             Rotate(i,0);
 59             Del(a[i].son[1],key);
 60         }
 61     }
 62     else if(a[i].key>key){
 63         Del(a[i].son[0],key);
 64     }
 65     else{
 66         Del(a[i].son[1],key);
 67     }
 68     up(i);
 69 }
 70 int Find(int i,int key){
 71     if(i==0) return 1;
 72     if(a[i].key>=key) return Find(a[i].son[0],key);
 73     else return a[a[i].son[0]].siz+Find(a[i].son[1],key)+1;
 74 }
 75 int Search(int i,int rak){
 76     if(a[a[i].son[0]].siz==rak-1) return a[i].key;
 77     if(a[a[i].son[0]].siz>=rak) return Search(a[i].son[0],rak);
 78     else  return Search(a[i].son[1],rak-a[a[i].son[0]].siz-1);
 79 }
 80 int pre(int i,int key){
 81     if(i==0) return -10000008;
 82     if(a[i].key<key) return max(a[i].key,pre(a[i].son[1],key));
 83     return pre(a[i].son[0],key);
 84 }
 85 int bhe(int i,int key){
 86     if(i==0) return 10000008;
 87     if(a[i].key>key) return min(a[i].key,bhe(a[i].son[0],key));
 88     return bhe(a[i].son[1],key);
 89 }
 90 int main(){
 91     int n;
 92     freopen("data1.in","r",stdin);
 93     freopen("data1.out","w",stdout);
 94     scanf("%d",&n);
 95     int opt,x;
 96     int sum=0;
 97     while(n--){
 98         scanf("%d%d",&opt,&x);
 99         if(opt==1){
100             Insert(root,x);
101             sum++;
102             vis[x]++;
103         }
104         if(opt==2){
105             if(vis[x]){
106                 Del(root,x);
107                 sum--;
108                 vis[x]--;
109             }
110         }
111         if(opt==3){
112             printf("%d
",Search(root,sum-x+1));
113         }
114         if(opt==4){
115             printf("%d
",sum-Find(root,x)+1);
116         }
117     }
118 }
View Code

F: 闲的无聊的简单题

Description

给你一个n*m的二维数组,a[i][j]表示第i行第j列的数字,现在求一个最大面积(长乘宽)的子矩形,要求对于该子矩形每一行中相邻的两个数,a[i][j]和a[i][j+1],存在一个整数k使得2的k次方同时小于等于a[i][j]和a[i][j+1],并且2的(k+1)次方大于a[i][j]和a[i][j+1],对于每一列中相邻的两个数,a[i][j]和a[i+1][j],不存在一个整数k使得2的k次方同时小于等于a[i][j]和a[i+1][j],并且2的(k+1)次方大于a[i][j]和a[i+1][j]。(0<n,m<=500)。

Input

第一行输入两个数n,m
接下来n行,每行m个整数第i行第j列表示a[i][j](0<a[i][j]<=1e9)

Output

输出一个表示符合要求的最大矩形面积

Examples

Input

4 4

1 2 3 4

5 6 7 8

9 10 11 12

13 14 15 16

Output

6

描述:

对于样例,面积为6的矩形如下
2 3
6 7
10 11

正确解法:

判断一个数a与另一个数b是否存在一个k满足可以用异或,令c=a^b,如果c同时小于a和b,则存在,否则则不存在。开三个数组up,l,r存每个点上边,左边和右边可以到达的最值,并且l和r不断更新,每次不断更新面积最大值即可。
 
 1 #include<bits/stdc++.h>
 2 #define fi first
 3 #define se second
 4 #define INF 0x3f3f3f3f
 5 #define fio ios::sync_with_stdio(false);cin.tie(0);cout.tie(0)
 6 #define pqueue priority_queue
 7 #define NEW(a,b) memset(a,b,sizeof(a))
 8 const double pi=4.0*atan(1.0);
 9 const double e=exp(1.0);
10 const int maxn=1e6+8;
11 typedef long long LL;
12 typedef unsigned long long ULL;
13 const LL mod=1e9+7;
14 const ULL base=1e7+7;
15 using namespace std;
16 int a[2008][2008];
17 int l[2008][2008],r[2008][2008],u[2008][2008];
18 int main(){
19     //freopen("data5.in","r",stdin);
20     //freopen("data5.out","w",stdout);
21     int n,m;
22     scanf("%d%d",&n,&m);
23     for(int i=1;i<=n;i++){
24         for(int j=1;j<=m;j++){
25             scanf("%d",&a[i][j]);
26         }
27         l[i][1]=1;r[i][m]=m;
28         int k;
29         for(int j=2;j<=m;j++){
30             k=a[i][j]^a[i][j-1];
31             if(a[i][j]>=k&&a[i][j-1]>=k){
32                 l[i][j]=l[i][j-1];
33             }
34             else{
35                 l[i][j]=j;
36             }
37         }
38         for(int j=m-1;j>=1;j--){
39             k=a[i][j]^a[i][j+1];
40             if(a[i][j]>=k&&a[i][j+1]>=k){
41                 r[i][j]=r[i][j+1];
42             }
43             else{
44                 r[i][j]=j;
45             }
46         }
47     }
48     int maxa=0;
49     for(int i=1;i<=n;i++){
50         for(int j=1;j<=m;j++){
51             if(i>1&&(a[i][j]<(a[i][j]^a[i-1][j])||a[i-1][j]<(a[i][j]^a[i-1][j]))){
52                 u[i][j]=u[i-1][j]+1;
53                 l[i][j]=max(l[i][j],l[i-1][j]);
54                 r[i][j]=min(r[i][j],r[i-1][j]);
55             }
56             else{
57                 u[i][j]=1;
58             }
59             maxa=max(maxa,(r[i][j]-l[i][j]+1)*u[i][j]);
60         }
61     }
62     //cout<<u[39][17]<<endl;
63     cout<<maxa<<endl;
64 }
View Code

G: 简单题*10086

Description

现有N个数c1,c2,...,cN。对于每个数求有多少个有序二元组(i,j)满足以下式子   

ci * cj mod P=ck(i,j,k可想等)

其中P为一给定质数。对于每个k对应的答案记为cnt[k],请你将每两个相邻的答案相加,这样答案总个数每次减少1,当答案个数为1时结束(结果对1e9+7取模)。为了感谢wjh、xxb、lmb、cly、ckx、yzj出了一堆简单题,请将他们名字缩写(小写)合并后去重并输出字典序第k大,k为所得结果乘上2333333后取模6666666的结果。

Input

第一行输入一个组数t(t ≤ 5)。
对于每组数据第一行有两个正整数N,P(1 ≤ N ≤ 100000,2 ≤ P ≤ 100000), P为质数。
第二行N个非负整数c1,c2,...,cN(0 ≤ ci ≤ 1e9)。

Output

输出共一行,为对应答案的字典序排列(答案为0输出-1)。

Examples

Input

2

7 3

1 2 3 4 5 6 7

5 7

1 0 2 3 0

Output

ckybhmwzxjl

byjlhwzmckx

正确解法:

例如答案是1 2 3 4 5那么你应该经过以下变化变成一个答案1 2 3 4 5 

3 5 7 9
8 12 16
20 28
48

 

我们令g为质数P的原根,那么对于一个数字ai,唯一存在一个数字bi,使得  。那么我们把所有的ai用这种形式表示,于是对于原本的式子ci*cj≡ck(mod P),有,那么可以有bi+bj=bk。这样问题就从乘法变成了加法,FFT就可以排上用场了。而且你会发现,这里的bi的大小都是在P以内的。这样直接FFT即可,最后特殊处理一下0的情况即可。而对于接下来的一部可以发现最后结果就是C(n-1,0)*a[1]+C(n-1,1)*a[2]+……+C(n-1,n-1)*a[n],可以O(n)求出答案,最后一步是个逆康托展开。

  1 #include <cstdio>
  2 #include <cstdlib>
  3 #include <cstring>
  4 #include <bitset>
  5 #include <cmath>
  6 #include <cctype>
  7 #include <iostream>
  8 #include <algorithm>
  9 #include <string>
 10 #include <vector>
 11 #include <queue>
 12 #include <map>
 13 #include <set>
 14 #include <sstream>
 15 #include <iomanip>
 16 using namespace std;
 17 typedef long long ll;
 18 typedef unsigned long long ull;
 19 const ll inff = 0x3f3f3f3f3f3f3f3f;
 20 #define FOR(i,a,b) for(int i(a);i<=(b);++i)
 21 #define FOL(i,a,b) for(int i(a);i>=(b);--i)
 22 #define REW(a,b) memset(a,b,sizeof(a))
 23 #define inf int(0x3f3f3f3f)
 24 #define si(a) scanf("%d",&a)
 25 #define sl(a) scanf("%lld",&a)
 26 #define sd(a) scanf("%lf",&a)
 27 #define ss(a) scanf("%s",a)
 28 #define mod ll(6666666)
 29 #define pb push_back
 30 #define eps 1e-6
 31 #define lc d<<1
 32 #define rc d<<1|1
 33 #define Pll pair<ll,ll>
 34 #define P pair<int,int>
 35 #define pi acos(-1)
 36 ll n,p,g,id[2000008],m,ans[5000008],pr[1000008],prime[1000008],qw[1000008],tot;
 37 ll a[100008],jc[15],inv[100008],mm=1e9+7,vis[15],sss[100008];
 38 char s[15],ss[5008];
 39 inline int read()
 40 {
 41     int X=0,w=0; char ch=0;
 42     while(!isdigit(ch)) {w|=ch=='-';ch=getchar();}
 43     while(isdigit(ch)) X=(X<<3)+(X<<1)+(ch^48),ch=getchar();
 44     return w?-X:X;
 45 }
 46 void init(int n)
 47 {
 48     int i,j;
 49     tot=0;
 50     prime[1]=1;
 51     for(i=2;i<=n;i++)
 52     {
 53         if(!prime[i]) prime[i]=pr[tot++]=i;
 54         for(j=0;j<tot&&pr[j]*i<=n;j++)
 55         {
 56             prime[i*pr[j]]=pr[j];
 57             if(i%pr[j]==0) break;
 58         }
 59     }
 60 }
 61 ll gmod(ll a,ll b,ll p)
 62 {
 63     ll res=1;
 64     while(b)
 65     {
 66         if(b&1) res=res*a%p;
 67         a=a*a%p,b>>=1;
 68     }
 69     return res;
 70 }
 71 int root(int x)
 72 {
 73     int f,phi=x-1;qw[0]=0;
 74     for(int i=0;phi&&i<tot;i++)
 75     {
 76         if(phi%pr[i]==0)
 77         {
 78             qw[++qw[0]]=pr[i];
 79             while(phi%pr[i]==0) phi/=pr[i];
 80         }
 81     }
 82     for(int g=2;g<=x-1;g++)
 83     {
 84         f=1;
 85         for(int i=1;i<=qw[0];i++)
 86          if(gmod(g,(x-1)/qw[i],x)==1) {f=0;break;}
 87         if(f) return g;
 88     }
 89     return 0;
 90 }
 91 struct CP{
 92     double x,y;
 93     CP(){} CP(double a,double b):x(a),y(b){}
 94     CP operator+(const CP&r) const{return CP(x+r.x,y+r.y);}
 95     CP operator-(const CP&r) const{return CP(x-r.x,y-r.y);}
 96     CP operator*(const CP&r) const{return CP(x*r.x-y*r.y,x*r.y+y*r.x);}
 97 }b[5000008],t;
 98 inline void Swap(CP&a,CP&b) {t=a;a=b;b=t;}
 99 inline void fft(CP*a,int f,int n)
100 {
101     int i,j,k;
102     for(i=j=0;i<n;i++)
103     {
104         if(i>j) Swap(a[i],a[j]);
105         for(k=n>>1;(j^=k)<k;k>>=1);
106     }
107     for(int i=1;i<n;i<<=1)
108     {
109         CP wn(cos(pi/i),f*sin(pi/i));
110         for(int j=0;j<n;j+=i<<1)
111         {
112             CP w(1,0);
113             for(int k=0;k<i;k++,w=w*wn)
114             {
115                 CP x=a[j+k],y=w*a[i+j+k];
116                 a[j+k]=x+y;a[i+j+k]=x-y;
117             }
118         }
119     }
120     if(f==-1) FOR(i,0,n) a[i].x/=n;
121 }
122 void rkt(ll n,ll k)
123 {
124     ll t,ty=0;
125     REW(vis,0);
126     n--;
127     FOR(i,0,k-1)
128     {
129         t=n/jc[k-i-1];
130         n%=jc[k-i-1];
131         for(ll j=0,pos=0;;j++,pos++)
132         {
133             if(vis[pos]) j--;
134             if(j==t){vis[pos]=1;s[ty++]=('a'+pos+1);break;}
135         }
136     }
137 }
138 int main()
139 {
140     cin.tie(0);
141     cout.tie(0);
142     freopen("date1.in","r",stdin);
143     freopen("date1.out","w",stdout);
144     int tt;
145     cin>>tt;
146     ss['b']='b',ss['c']='c',ss['d']='h',ss['e']='j',ss['f']='k',ss['g']='l';
147     ss['h']='m',ss['i']='w',ss['j']='x',ss['k']='y',ss['l']='z';
148     jc[0]=jc[1]=1;
149     for(ll i=2;i<=12;i++) jc[i]=jc[i-1]*i;
150     inv[1]=1;
151     FOR(i,2,100005)  inv[i]=(mm-mm/i)*inv[mm%i]%mm;
152     init(100000);
153     while(tt--)
154     {
155         cin>>n>>p;
156         g=root(p);
157         ll tmp=1,qw=0,er,sum=1;
158         for(int i=1;i<p-1;i++)
159         {
160             tmp=tmp*g%p;
161             id[tmp]=i;
162         }
163         er=m=p-1;
164         for(m=er+m,er=1;er<=m;er<<=1);
165         FOR(i,0,er+1) b[i].x=b[i].y=0.0,ans[i]=0;
166         FOR(i,1,n)
167         {
168             a[i]=read();
169             if(!(a[i]%p)) qw++;
170             else b[id[a[i]%p]].x+=1.0;
171         }
172         fft(b,1,er);
173         FOR(i,0,er) b[i]=b[i]*b[i];
174         fft(b,-1,er);
175         for(int i=0;i<2*p;i++) ans[i%(p-1)]+=(ll)(b[i].x+0.2);
176         for(int i=1;i<=n;i++)
177         {
178             if(a[i]>=p) er=0;
179             else if (a[i]==0) er=2*qw*n-qw*qw;
180             else er=ans[id[a[i]]];
181             sss[i]=er;
182         }
183         er=0;
184         for(int i=0;i<n;i++)
185         {
186             er=(er+sum*sss[i+1])%mm;
187             sum=(sum*(n-1-i)%mm)*inv[i+1]%mm;
188         }
189         //cout<<er<<endl;
190         er=((er%mod)*2333333)%mod;
191         if(er==0) {puts("-1");continue;}
192         rkt(er,11);
193         for(int i=0;i<11;i++) printf("%c",ss[s[i]]);
194         puts("");
195     }
196     return 0;
197 }
View Code

 

H: 简单题*10000

Description

已知一排硬币中有n个硬币正面朝上,输入正面朝上的硬币的位置ai(可能重复)。
两人轮流操作,每次操作可以翻转1,2,或则3枚硬币(不一定连续),其中翻转的最右的硬币必须是正面朝上的,最后不能翻转的为负

Input

第一行输入一个组数t(t ≤ 100)。

对于每组数据第一行有一个正整数N(0 ≤ N ≤ 5000)。

第二行N个非负整数c1,c2,...,cN(0 ≤ ai ≤ 1e9)。

Output

如果先手必胜输出Yes,否则输出No。

Examples

Input

2

1

0

4

0 1 2 3

Output

Yes

No

正确解法:

定义硬币全反时的sg为0,现在单个游戏就是只有一枚硬币朝上,其余都是反,其他情况都可以由单一游戏组合而成。如果位置i有一个正面朝上的硬币,其余都是反,那么这枚硬币翻过来的时候,它可以到达的局面是1、sg = 0   2、sg(j)j位置的硬币朝上,其余都是反(j<i) 3、出现两个正面朝上的硬币,变成组合游戏sg(j)和sg(k)。我们把sg函数打表出来就可以找到规律。(hdu3537)

初始编号从0开始。

当N==1时,硬币为:正,先手必胜,所以sg[0]=1.

当N==2时,硬币为:反正,先手必赢,先手操作后可能为:反反或正反,方案数为2,所以sg[1]=2。

当N==3时,硬币为:反反正,先手必赢,先手操作后可能为:反反反、反正反、正反正、正正反,方案数为4,所以sg[2]=4。

位置x:0  1  2  3  4   5    6   7    8     9  10  11  12  13  14...

sg[x]:  1  2  4  7  8  11 13 14  16  19  21  22  25  26  28…

看上去sg值为2x或者2x+1。我们称一个非负整数为odious,当且仅当该数的二进制形式的1出现的次数是奇数,否则称作evil。所以1,2,4,7是odious因为它们的二进制形式是1,10,100,111.而0,3,5,6是evil,因为它们的二进制形式是0,11,101,110。而上面那个表中,貌似sg值都是odious数。所以当2x为odious时,sg值是2x,当2x是evil时,sg值是2x+1.

这样怎么证明呢?我们会发现发现,

                                                     evil^evil=odious^odious=evil

                                                     evil^odious=odious^evil=odious

假设刚才的假说是成立的,我们想证明下一个sg值为下一个odious数。注意到我们总能够在第x位置翻转硬币到达sg为0的情况;通过翻转第x位置的硬币和两个其它硬币,我们可以移动到所有较小的evil数,因为每个非零的evil数都可以由两个odious数异或得到;但是我们不能移动到下一个odious数,因为任何两个odious数的异或都是evil

假设在一个Mock Turtles游戏中的首正硬币位置x1,x2,…,xn是个P局面,即sg[x1]^…^sg[xn]=0.那么无可置疑的是n必定是偶数,因为奇数个odious数的异或是odious数,不可能等于0。而由上面可知sg[x]是2x或者2x+1,sg[x]又是偶数个,那么x1^x2^…^xn=0。相反,如果x1^x2^…^xn=0且n是偶数,那么sg[x1]^…^sg[xn]=0。这个如果不太理解的话,我们可以先这么看下。2x在二进制当中相当于把x全部左移一位,然后补零,比如说2的二进制是10,那么4的二进制就是100。而2x+1在二进制当中相当于把x全部左移一位,然后补1,比如说2的二进制是10,5的二进制是101。现在看下sg[x1]^…^sg[xn]=0,因为sg[x]是2x或者2x+1,所以式子中的2x+1必须是偶数个(因为2x的最后一位都是0,2x+1的最后一位都是1,要最后异或为0,2x+1必须出现偶数次)

 
 1 #include <cstdio>
 2 #include <cstdlib>
 3 #include <cstring>
 4 #include <bitset>
 5 #include <cmath>
 6 #include <cctype>
 7 #include <iostream>
 8 #include <algorithm>
 9 #include <string>
10 #include <vector>
11 #include <queue>
12 #include <map>
13 #include <set>
14 #include <sstream>
15 #include <iomanip>
16 using namespace std;
17 typedef long long ll;
18 typedef unsigned long long ull;
19 const ll inff = 0x3f3f3f3f3f3f3f3f;
20 #define FOR(i,a,b) for(int i(a);i<=(b);++i)
21 #define FOL(i,a,b) for(int i(a);i>=(b);--i)
22 #define REW(a,b) memset(a,b,sizeof(a))
23 #define inf int(0x3f3f3f3f)
24 #define si(a) scanf("%d",&a)
25 #define sl(a) scanf("%lld",&a)
26 #define sd(a) scanf("%lf",&a)
27 #define ss(a) scanf("%s",a)
28 #define mod ll(6666666)
29 #define pb push_back
30 #define eps 1e-6
31 #define lc d<<1
32 #define rc d<<1|1
33 #define Pll pair<ll,ll>
34 #define P pair<int,int>
35 #define pi acos(-1)
36 int n,a[100008];
37 int as(int x)
38 {
39     int k=0;
40     while (x)
41     {
42         if (x&1) k++;
43         x>>=1;
44     }
45     return !(k&1);
46 }
47 int main()
48 {
49     cin.tie(0);
50     cout.tie(0);
51     //freopen("game001.in","r",stdin);
52     //freopen("game001.out","w",stdout);
53     int tt;
54     cin>>tt;
55     while(tt--)
56     {
57         si(n);
58         FOR(i,1,n) si(a[i]);
59         sort(a+1,a+n+1);
60         int k=unique(a+1,a+n+1)-a-1,s=0;
61         FOR(i,1,k)
62         {
63             a[i]*=2ll;
64             if(as(a[i])) a[i]++;
65             s^=a[i];
66         }
67         if(s) puts("Yes");
68         else puts("No");
69     }
70     return 0;
71 }
View Code

 

I: 水题

Description

史努比最爱水题了,他知道现在他要挑战的是一道超级大水题哦。不过因为太水了,而且他又很懒,所以把这道水题推给了你们。

有n个(不包括ZSTU和火车东站)车站介于ZSTU和火车东站之间,一共有m辆公交车往返于这些车站和火车东站。每个车站假设可以站无数个人,每辆车最多承载H[i]个人,经过S[i]个车站。假设一辆车依次经过1,2,3,这三个车站,那么它将一直往复1->2->3->1->2...现在认为车从一个站到下一个站要花费1个小时,人只能在车站或ZSTU,火车东站上下车,初始时有k个人在ZSTU(0站),所有的车都在初始站(所给车站的第一个车站为初始站),现在问你们最快让全部人从ZSTU到火车东站要多少小时。所有车同时运行。

Input

第一行有一个T<=10,表示T组测试样例,第二行三个数n(车站数目),m(车数目),k(人数),(n<=13,m<=20,k<=50);接下来的m行给出车信息,每行给出H[i](能承载的最大人数),S[i](经过的车站数目),还有依次给出S[i]个车站编号。ZSTU用0编号表示,火车东站用-1表示。

Output

若无解则输出-1,否则逐行输出答案。

Examples

Input

2

2 2 1

1 3 0 1 2

1 3 1 2 -1

2 3 3

1 2 0 2

1 2 1 2

1 2 1 -1

Output

5

7

正确解法:

第一个样例,一人从0站乘坐1号公交车途径1站,到2站下车,花费2S;此时2号车位于-1站,再经过2S,2号车从-1站途径1站到2站,人上2号车再经过1S到达-1站,共花费5S。或者一人从0站乘坐一号公交车到1站下车,花费1S,此时2号车位于2站,再经过2S到1站,人上2号车再经过2S到达-1站,共花费5S。

首先判断学校到火车东站能不能到站,即是否在同一个集团里面,用并查集就可以了。然后跑网络流,网络流跑一次后会更改原来储存的边的信息,因此可以枚举时间进行网络流,按照时间建边,在上一个时间段跑网络流的基础上,继续建图在继续跑网络流,将每次的最大流加起来直到总和大于等于k就可以返回当前天数了。

具体操作是将第i-1小时的第j个车的信息向第i小时的第j个车进行连边,容量为INF,将每辆车第i-1小时所待的公交车站向第i小时所待的公交车站连边,容量为车的最大载人数。

 

  1 #include <bits/stdc++.h>
  2 //CLOCKS_PER_SEC
  3 #define se second
  4 #define fi first
  5 #define ll long long
  6 #define lson l,m,rt<<1
  7 #define rson m+1,r,rt<<1|1
  8 #define Pii pair<int,int>
  9 #define Pli pair<ll,int>
 10 #define ull unsigned long long
 11 #define pb push_back
 12 #define fio ios::sync_with_stdio(false);cin.tie(0)
 13 const double Pi=3.14159265;
 14 const int N=1e3+5;
 15 const ull base=163;
 16 const int INF=0x3f3f3f3f;
 17 using namespace std;
 18 int n,m,k,s,t;
 19 int head[10100],to[100010],cur[10100],nx[100010];
 20 int cap[100010];
 21 int tot=0;
 22 void add(int x,int y,int c){
 23     to[tot]=y;
 24     nx[tot]=head[x];
 25     cap[tot]=c;
 26     head[x]=tot++;
 27     
 28     to[tot]=x;
 29     nx[tot]=head[y];
 30     cap[tot]=0;
 31     head[y]=tot++;
 32 }
 33 void init(int n){
 34     tot=0;
 35     memset(head,-1,sizeof(head));
 36 }
 37 int d[N];
 38 int bfs(){
 39     memset(d,-1,sizeof(d));
 40     queue<int>q;
 41     q.push(s);
 42     d[s]=1;
 43     while(!q.empty()){
 44         int u=q.front();q.pop();
 45         for(int i=head[u];~i;i=nx[i]){
 46             int v=to[i];
 47             if(d[v]==-1&&cap[i]>0){
 48                 d[v]=d[u]+1;
 49                 q.push(v);
 50             }
 51         }
 52     }
 53     return d[t]!=-1;
 54 }
 55 int dfs(int s,int a){
 56     if(s==t||a==0)return a;
 57     int flow=0,f;
 58     for(int &i=cur[s];~i;i=nx[i]){
 59         int v=to[i];
 60         if(d[s]+1==d[v] && cap[i]>0 && (f=dfs(v,min(a,cap[i])))>0){
 61             flow+=f;
 62             cap[i]-=f;
 63             cap[i^1]+=f;
 64             a-=f;
 65             if(a==0)break;
 66         }
 67     }
 68     return flow;
 69 }
 70 int dinic(){
 71     int ans=0;
 72     while(bfs()){
 73         for(int i=0;i<=1000;i++)cur[i]=head[i];
 74         while(int di=dfs(s,INF)){
 75             ans+=di;
 76         }
 77     }
 78     return ans;
 79 }
 80 int ship[N][N];
 81 int num[N];
 82 int r[N];
 83 int fa[N];
 84 int F(int x){
 85     return fa[x]==x?x:fa[x]=F(fa[x]);
 86 }
 87  
 88 bool check(int x,int y){
 89     if(F(x)==F(y))return 1;
 90     else return 0;
 91 }
 92 int cal(int a,int d){
 93     return d*n+a;
 94 }
 95 void solve(){
 96     int flow=0;
 97     int i;
 98     init(n);// n -1     n-1   0
 99     add(s,cal(n-1,0),INF);
100     add(cal(n,0),t,INF);
101     for(i=1;flow<k;i++){
102         add(s,cal(n-1,i),INF);add(cal(n,i),t,INF);
103         for(int j=1;j<=n;j++){
104             add(cal(j,i-1),cal(j,i),INF);
105         }
106         for(int j=1;j<=m;j++){
107             int a=(i-1)%num[j]+1;
108             int b=i%num[j]+1;
109             add(cal(ship[j][a],i-1),cal(ship[j][b],i),r[j]);
110         }
111         flow+=dinic();
112         
113     }
114    printf("%d
",i-1);
115 }
116 int main(){
117      // clock_t start, end;
118     int T;scanf("%d",&T);
119     while(T--){
120         s=0,t=1000;
121         scanf("%d%d%d",&n,&m,&k);
122         for(int i=0;i<=n+2;i++)fa[i]=i;
123         for(int i=1;i<=m;i++){
124             scanf("%d%d",&r[i],&num[i]);
125             for(int j=1;j<=num[i];j++){
126                 scanf("%d",&ship[i][j]);
127                 if(ship[i][j]==0)ship[i][j]=n+1;
128                 if(ship[i][j]==-1)ship[i][j]=n+2;
129                 if(j>1){
130                     fa[F(ship[i][j-1])]=F(ship[i][j]);
131                 }
132             }
133         }
134         n+=2;
135         if(check(n, n-1)){
136             solve();
137         }
138         else{
139             printf("0
");
140         }
141     }
142     // end = clock();
143     // cout << "time :"<<(double)(end - start) / CLOCKS_PER_SEC << endl;
144     return 0;
145 }
146 /*
147 */
View Code

 

K: 快乐树论

Description

曾经有一位伟大的皇帝,他拥有n座城池并用n-1条无向道路相连,每条道路均有一个确定的长度和两个端点,保证城池与城池之间互达。有一天,皇帝决定将其中一条路拆掉,并重新将这条道路以同样的长度搭在两座城池之间,皇帝可能将这条路拆了又重新建在原处。现在皇帝想问问你,在只拆掉一条道路并重新建造一条同样长的在两座城池之间后,任意两个城池之前的距离和最小为多少呢?

Input

第一行输入一个n代表皇帝有n座城池,接下来n-1行输入a,b,c代表城池a,b之间有一条长为c的道路。 (2 ≤ n ≤ 5000, 1 ≤ ai, bi ≤ n, ai ≠ bi, 1 ≤ wi ≤ 106)

Output

 输出一行任意两城池之间的最小距离和。

Examples

Input

输入样例1:

3

1 2 2

1 3 4

输入样例2:

6

1 2 1

2 3 1

3 4 1

4 5 1

5 6 1

输入样例3:

6

1 3 1

2 3 1

Output

12

29

85

正确解法:

具体证明参考:https://blog.csdn.net/zhoufenqin/article/details/9821617

 1 #include<bits/stdc++.h>
 2  
 3 #define fi first
 4 #define se second
 5 #define pb push_back
 6  
 7 using namespace std;
 8  
 9 typedef long long ll;
10 typedef pair<ll,ll> Pll;
11  
12 const ll LLMAX=2e18;
13 const int MAXN=1e6+10;
14  
15 struct node{
16     int u,v;
17     ll w;
18 }in[MAXN];
19  
20 ll dp[MAXN][3];
21 vector<Pll>G[MAXN];
22  
23 void dfs(int u,int pre){
24     dp[u][0]=dp[u][1]=dp[u][2]=0;
25     for(int i=0;i<G[u].size();i++){
26         int v=G[u][i].fi,w=G[u][i].se;
27         if(v==pre)   continue;
28         dfs(v,u);
29         dp[u][2]+=dp[v][2]+dp[v][1]*dp[u][0]+dp[v][0]*dp[u][1]+dp[u][0]*dp[v][0]*w;
30         dp[u][1]+=dp[v][1]+dp[v][0]*w;
31         dp[u][0]+=dp[v][0];            
32     }
33     dp[u][0]++;
34     dp[u][2]+=dp[u][1];
35 }
36  
37 void solve(int u,int pre,ll &ans){
38     ans=min(ans,dp[u][1]);
39     for(int i=0;i<G[u].size();i++){
40         int v=G[u][i].fi,w=G[u][i].se;
41         if(v==pre)  continue;
42         dp[v][1]=dp[v][1]+(dp[u][1]-dp[v][1]-w*dp[v][0])+(dp[u][0]-dp[v][0])*w;
43         dp[v][0]=dp[u][0];
44         solve(v,u,ans);
45     }
46 }
47  
48 int main(void)
49 {
50     ios::sync_with_stdio(false);    cin.tie(0);
51     ll n,ans=LLMAX;  cin>>n; 
52     for(int i=1;i<n;i++){
53         ll x,y,v;  cin>>x>>y>>v;    
54         in[i].u=x,in[i].v=y,in[i].w=v;
55         G[x].pb(Pll(y,v)),G[y].pb(Pll(x,v));
56     }
57     for(int i=1;i<n;i++){
58         ll ans1=LLMAX,ans2=LLMAX,u=in[i].u,v=in[i].v,w=in[i].w;
59         dfs(u,v);   solve(u,v,ans1);
60         ll len1=(n-dp[u][0])*ans1+dp[u][2];
61         dfs(v,u);   solve(v,u,ans2);
62         ll len2=(n-dp[v][0])*ans2+dp[v][2];
63         ans=min(ans,len1+len2+dp[u][0]*dp[v][0]*w);
64     }
65     cout<<ans<<endl;
66     return 0;
67 }
View Code

L: 快乐数论

Description

给出正整数n,k,要求使正整数n拆分成若干个正整数的和,并且使得拆分后的数中相同的数的出现次数小于k次。

Input

第一行输入T,共有T组测试样例,接下来2~T+1行,每行输入n,k。 1<=n,k,T<=10^5

Output

输出T行,每行对应的拆分方案,最后答案取模1e9+7

Examples

Input

4

4 2

4 3

4 4

4 5

Output

2

4

4

5

正确解法:

n=4,k=2时,可拆分成4=4,4=1+3

n=4,k=3时,可拆分成4=1+2+1,4=2+2,4=1+3,4=4

 

 1 #include<bits/stdc++.h>
 2  
 3 using namespace std;
 4  
 5 typedef long long  ll;
 6  
 7 const int MOD=1e9+7;
 8 const int MAXN=1e6+10;
 9  
10 ll p[MAXN];
11  
12 void init(){
13     p[0]=1;
14     for(ll i=1;i<=100000;i++){
15         for(ll j=1,w=1;w<=i;j++,w=(3*j*j+j)/2)
16             if(j&1) p[i]=(p[i]+p[i-w])%MOD;
17             else    p[i]=((p[i]-p[i-w])%MOD+MOD)%MOD;
18         for(ll j=1,w=2;w<=i;j++,w=(3*j*j-j)/2)
19             if(j&1) p[i]=(p[i]+p[i-w])%MOD;
20             else    p[i]=((p[i]-p[i-w])%MOD+MOD)%MOD;
21     }
22 }
23  
24 ll solve(ll n,ll k){
25     ll ans=p[n];
26     for(ll j=1,w=k;w<=n;j++,w=k*(3*j*j+j)/2)
27         if(j&1) ans=((ans-p[n-w])%MOD+MOD)%MOD;
28         else    ans=(ans+p[n-w])%MOD;
29     for(ll j=1,w=2*k;w<=n;j++,w=k*(3*j*j-j)/2)
30         if(j&1) ans=((ans-p[n-w])%MOD+MOD)%MOD;
31         else    ans=(ans+p[n-w])%MOD;
32     return ans;
33 }
34  
35 int main(void)
36 {
37     init();
38     int T;  cin>>T;
39     while(T--){
40         ll n,k;   scanf("%lld%lld",&n,&k);
41         printf("%lld
",solve(n,k));
42     }
43     return 0;
44 }
View Code

 

 M: 看电影

Description

wjh要去看电影,邀请了lmb,xxb,cly,yzj,ckx等人,最后有k个人同意一起去。要去的电影院的位置是矩阵型的,其中’#’表示已经被人预定了,’*’表示空位,他们打算挑同一行或者同一列连续的座位坐在一起,现在给出k和位置的预定请况,试问有几种坐位置的方法。

Input

第一行输入两个数n和k,n表示电影院的位置是n*n的。(0<n<=10,0<=k<10)
接下在n行,每行n个字符,表示位置的预订情况。

Output

 一行输出有几种坐法。

Examples

Input

4 1

**##

*###

####

####

Output

4

正确解法:

暴力纵向横向搜索一下。

当k为0时,答案要除2。

No matter how you feel, get up , dress up , show up ,and never give up.
原文地址:https://www.cnblogs.com/Kaike/p/9905392.html