A
题目大意
选择范围在 [ 1 , 2 m ) [1,2^m) [1,2m)内的任意n个数组成一个长度为n的序列,当且仅当序列序列每个位置上的数均不相等时序列不同,需求得该序列内任意一个子序列满足其所有数的AND后的结果为 1 1 1的序列个数
题解
若一些数的AND后结果为1,需保证其二进制第一位均为1,其他位不全为1,由于题目内每个位置均能填任意数,需要用更宏观的角度来看其位置信息,主要观察的就是
- 二进制内如何保证其他位不全为1
- 如何去找到这个子序列,同时保证不重复
注意到子序列,可以发现,事实上,对该子序列产生影响的只有奇数,换言之,偶数由于其二进制末位为0,永远不可放入子序列,现在考虑如何考察奇数,并使其不重复。
可以发现,无需考察奇数的子集,故可以考虑奇数的个数,
不妨假设此时考虑的奇数为
k
k
k个,那么偶数为
n
−
k
n-k
n−k个,此时固定奇数的位置,其共有
C
(
n
,
k
)
C(n,k)
C(n,k)个位置可以选择,剩下的均为偶数,考虑偶数的选择,偶数可以任选,故为
(
2
m
−
1
)
n
−
k
(2^{m-1})^{n-k}
(2m−1)n−k个,考虑奇数的选择,奇数需要保证每个二进制位不全为1,就是去除全为1的选择,故为
(
2
i
−
1
)
m
−
1
(2^i-1)^{m-1}
(2i−1)m−1
所以最后的答案就是 C ( n , k ) ∗ ( 2 m − 1 ) n − k ∗ ( 2 i − 1 ) m − 1 C(n,k)*(2^{m-1})^{n-k}*(2^i-1)^{m-1} C(n,k)∗(2m−1)n−k∗(2i−1)m−1
不要忘记在其中取模
代码
import heapq
import sys,math
input=lambda:sys.stdin.readline()
write=lambda x:sys.stdout.write(str(x)+'\n')
def calC_2(n, m, p):
res = [[0] * (1 + n) for _ in range(1 + n)]
## 初始化
for i in range(1 + n):
res[i][0] = res[i][i] = 1
for i in range(2, 1 + n):
for j in range(i // 2 + 1):
res[i][j] = (res[i - 1][j - 1] + res[i - 1][j]) % p
res[i][i - j] = res[i][j]
return res
n,m,p = map(int,input().split())
rr = calC_2(n,m,p)
res = 0
for i in range(1,n + 1):
res += (rr[n][i] * (pow(pow(2,n-i,p),m-1,p)) * (pow((pow(2,i,p) - 1),m-1,p)))%p
res %= p
print(res)代码片
C
题目大意
维护一个序列,每次操作会移除该序列的末尾 t t t个数,同时会往末尾增加一个大小为 v v v的数,询问每次操作后的后缀和总和
题解
直接维护总和,然后每次操作,直接遍历减掉末尾的数乘上它被加的个数 t t t次,最后加入即可
代码
import heapq
import sys,math
input=lambda:sys.stdin.readline()
write=lambda x:sys.stdout.write(str(x)+'\n')
res = 0
nn = 0
temp = []
mod = int(1e9) + 7
for _ in range(int(input())):
a,b = map(int,input().split())
for i in range(a):
tt = temp.pop()
res -= (nn - i) * tt
res %= mod
nn -= a
nn += 1
temp.append(b)
res += b * nn
res %= mod
print(res)
H
题目大意
有两场 World Finals 同时举办,每场都有若干出线队伍,两场出线名单
可能有重复的队伍,而一个队伍只能选择其中的一场参加,每场比赛的每支队伍都有一个预测成绩(过题数 + 罚时)
lzr010506 在两场 World Finals 都出线了,他想知道如果所有队伍的最终成绩就是预测成绩,并且可以任意分配两场都出线了队伍的比赛场次的选择,他们队最高可能的排名是多少
题解
模拟,如果lzr010506参加第一场,那么就把可以参加一二场的队伍都放入第二场,同理,如果lzr010506参加第二场,那么就把可以参加一二场的队伍都放入第一场
代码
import heapq
import sys,math
input=lambda:sys.stdin.readline()
write=lambda x:sys.stdout.write(str(x)+'\n')
n = int(input())
tmp1 = []
for i in range(n):
x = input().split()
tmp1.append([x[0], int(x[1]), int(x[2])])
tmp2 = []
m = int(input())
for i in range(m):
x = input().split()
tmp2.append([x[0], int(x[1]), int(x[2])])
tmp1.sort(key=lambda x: [-x[1], x[2]])
tmp2.sort(key=lambda x: [-x[1], x[2]])
res2 = set()
for i in tmp2:
res2.add(i[0])
cnt = 1
ans = 1000000
for i in tmp1:
if i[0] == 'lzr010506':
ans = min(ans, cnt)
break
if i[0] in res2:
continue
cnt += 1
cnt = 1
res1 = set()
for i in tmp1:
res1.add(i[0])
for i in tmp2:
if i[0] == 'lzr010506':
ans = min(ans, cnt)
break
if i[0] in res1:
continue
cnt += 1
print(ans)
I
题目大意
在大小为 n ∗ m n*m n∗m的空间内存在镜子,需求得每次询问光线经过的镜子总数
题解
由于光线的反射性,故不存在某块镜子有两条同样的路径,故最后光线的路径必然是一个环或者一条链,对其进行判断,得到答案即可。
代码
#include <iostream>
#include <fstream>
#include <string>
#include <algorithm>
using namespace std;
const int N=1e3+5;
int ans[100005], anstype[100005];
int val[N][N][4];
int mp[N][N], vis[N][N][4], cir[N][N][4];
int to[4][4]={0, 1, 3, 2, 1, 0, 2, 3, 3, 2, 1, 0, 2, 3, 0, 1};
int tx[4]={-1, 1, 0, 0};
int ty[4]={0, 0, -1, 1};
int n, m, q, sx, sy;
int dfs(int x, int y, int d, int cnt){
if(x<1 || x>n || y<1 || y>m){
//cout<<x<<" "<<y<<"\n";
return 0;
}
if(vis[x][y][d]){
cir[x][y][d]=1;
return cnt;
}
if(cir[x][y][d]){
return val[x][y][d];
}
int tmpd=to[mp[x][y]][d];
int flag=1;
for(int i=0; i<4; ++i){
if(vis[x][y][i]){
flag=0;
break;
}
}
if(flag && tmpd!=d){
flag=1;
}else{
flag=0;
}
if(tmpd!=d) vis[x][y][d]=1;
//cout<<"test: "<<x<<" "<<y<<" "<<mp[x][y]<<" "<<d<<" "<<tmpd<<" "<<cnt<<"\n";
int dx=x+tx[tmpd], dy=y+ty[tmpd], tmp=dfs(dx, dy, tmpd, cnt+flag);
if(tmpd!=d) vis[x][y][d]=0;
if(cir[dx][dy][tmpd]){
val[x][y][d]=tmp;
cir[x][y][d]=1;
}
else val[x][y][d]=tmp+flag;
return val[x][y][d];
}
int main(){
ios::sync_with_stdio(0);cin.tie(0);cout.tie(0);
//ifstream infile("E:\\Contest\\nc\\27.in", ios::in);
cin>>n>>m;
for(int i=1; i<=n; ++i){
for(int j=1; j<=m; ++j){
char c;
cin>>c;
if(c=='|'){
mp[i][j]=0;
}else if(c=='-'){
mp[i][j]=1;
}else if(c=='/'){
mp[i][j]=2;
}else{
mp[i][j]=3;
}
for(int k=0; k<4; ++k){
val[i][j][k]=-1;
}
}
}
cin>>q;
for(int i=1; i<=q; ++i){
int d;
string dir;
cin>>sx>>sy>>dir;
if(dir[0]=='a'){
d=0;
}else if(dir[0]=='b'){
d=1;
}else if(dir[0]=='l'){
d=2;
}else{
d=3;
}
// ans[i]=dfs(sx+tx[d], sy+ty[d], d, 0);
// anstype[i]=cir[sx+tx[d]][sy+ty[d]][d];
cout<<dfs(sx+tx[d], sy+ty[d], d, 0)<<"\n";
}
// infile.close();
// ifstream ansfile("E:\\Contest\\nc\\27.out", ios::in);
// for(int i=1, realans; i<=q; ++i){
// ansfile>>realans;
// if(realans!=ans[i]){
// cout<<"Real: "<<realans<<" WA: "<<ans[i]<<" type: "<<anstype[i]<<"\n";
// }
// }
// ansfile.close();
return 0;
}