A
题意:邀请k个人来,m次开门操作,每次操作有x,y表示x个人来之后开门,这次开门能进来y个人。礼物最贵的先进,如果一样先来的先进。如果m次开门操作后还有没进来的,就都进来。给q个询问,第x个进来的人是谁。
思路:优先队列维护下。
Code:
#include <bits/stdc++.h>
#pragma comment(linker, “/STACK:1024000000,1024000000”)
#define INF 0x3f3f3f3f
#define LL long long
using namespace std;
const int AX = 150000+6;
const int maxn = 50000+6;
struct Node{
char s[201];
int id ;
int v ;
bool friend operator < ( const Node a , const Node &b ){
return ( ( a.v == b.v && a.id > b.id) || ( a.v < b.v ) );
}
}a[AX];
struct M{
int num ;
int t ;
bool friend operator < ( const M a , const M &b ){
return ( a.t < b.t );
}
}b[AX];
Node res[maxn];
int main(){
int T;
scanf("%d",&T);
priority_queue<Node> que;
while( T-- ){
int k , m , q ;
int tot = 0 ;
while( !que.empty() ) que.pop();
scanf("%d%d%d",&k,&m,&q);
for( int i = 0 ; i < k; i++ ){
scanf("%s%d",a[i].s,&a[i].v);
a[i].id = i ;
}
for( int i = 0; i < m ; i++ ){
scanf("%d%d",&b[i].t,&b[i].num);
}
sort( b , b + m );
int cur = 0 ;
for( int i = 0 ; i < m ; i++ ){
while( cur < b[i].t ){
que.push( a[cur++] );
}
int tmp = b[i].num;
while( !que.empty() && tmp ){
res[tot++] = que.top();
que.pop();
tmp -- ;
}
}
while( cur < k ){
que.push(a[cur++]);
}
while( !que.empty() ){
res[tot++] = que.top();
que.pop();
}
int x ;
for( int i = 0 ; i < q - 1 ; i++ ){
scanf("%d",&x);
printf("%s ",res[x-1].s);
}
scanf("%d",&x);
printf("%s\n",res[x-1].s);
}
return 0 ;
}
题意:区间最值。
思路:线段树裸题。
Code:
#include <bits/stdc++.h>
#define INF 0x3f3f3f3f
#define LL long long
using namespace std;
const int AX = 1e6+6;
LL a[AX<<2];
void pushUp( int rt ){
a[rt] = max( a[rt<<1] , a[rt<<1|1] );
}
void build_tree(int l,int r ,int rt) {
if(l == r){
scanf("%ld",&a[rt]);
return;
}
int mid = (l+r) >> 1;
build_tree(l,mid,rt<<1);
build_tree(mid+1,r,rt<<1|1);
pushUp(rt);
}
int query_MAX( int L , int R , int l , int r , int rt ){
if( L <= l && R >= r ) return a[rt];
int ans = -INF;
int mid = ( l + r ) >> 1;
if( L <= mid) ans = max( ans , query_MAX( L , R , l , mid , rt << 1 ) ) ;
if( R > mid ) ans = max( ans , query_MAX( L , R , mid + 1 , r , rt << 1 | 1 ) ) ;
return ans ;
}
int main(){
int n , m;
int T;
scanf("%d",&T);
while( T-- ){
memset( a , 0 , sizeof(a) );
scanf("%d",&n);
build_tree( 1 , n , 1 );
int q;
scanf("%d",&q);
int l ,r ;
while( q-- ){
scanf("%d%d",&l,&r);
printf("%d\n",query_MAX(l,r,1,n,1));
}
}
return 0 ;
}
H
题意:给一个序列从根节点开始建树,比一个节点大的就放在E,小的就放在W方向,问从根节点开始到给定节点x,路径是什么。
思路:排序二叉树
Code:
#include <bits/stdc++.h>
using namespace std;
const int AX = 1e3+66;
int a[AX];
struct Node{
Node *l ;
Node *r ;
int v ;
bool vis ;
Node( ){
l = NULL; r = NULL; vis = false; v = 0;
}
} ;
Node *root ;
void insert( Node *t , int x ){
if( !t -> v ) t -> v = x;
else if( x < t -> v ){
if( !t -> l ) t -> l = new Node;
insert( t -> l , x );
}else{
if( !t -> r ) t -> r = new Node;
insert( t -> r , x );
}
}
void print( Node *t , int x ){
if( t -> v == x ){
return;
}
if( x < t -> v ){
printf("E");
print( t -> l , x );
}else{
printf("W");
print( t -> r , x );
}
}
int main(){
int T;
scanf("%d",&T);
while( T-- ){
int n;
root = new Node;
scanf("%d",&n);
for (int i = 1 ; i <= n ; i ++ ) {
scanf("%d",&a[i]);
insert(root,a[i]);
}
int q;
scanf("%d",&q);
int x ;
for( int i = 0 ; i < q ; i++ ){
scanf("%d",&x);
if( x != a[1] ){
print( root , x );
}
if( i != q - 1 ) printf("\n");
}
if( T ) printf("\n");
}
return 0;
}
J
题意:求C( n ,m ) % mod ( mod = p1 * p2 * p3 ** pk ) ( k < = 10 ) 且pi互不相同。
思路:大组合数取模: 卢卡斯定理+CRT。
C( n, m ) % mod 相当于求 C(n,m) % pi (1<=i<=k) 再用CRT合并。
#include <bits/stdc++.h>
using namespace std;
const int INF = 0x3f3f3f3f;
const int MOD = 1e9+7;
const int MAXN = 2e5+10;
#define LL long long
LL qmul(LL a,LL p,LL m){
LL tmp = 0;
while(p){
if(1&p) tmp = (tmp+a)%m;
a = (a+a)%m;
p>>=1;
}
return tmp;
}
void exgcd(LL a,LL b,LL &x,LL &y,LL &d){
if(!b) d=a,x = 1,y=0;
else exgcd(b,a%b,y,x,d),y-=(a/b)*x;
}
LL inv(LL a,LL p){
LL x,y,d;
exgcd(a,p,x,y,d);
return d==1?(x+p)%p:-1;
}
LL fat(LL x,LL p){
LL ans = 1;
for( int i = 2 ; i <= x ; i ++ ) ans = ( ans * i ) % p;
return ans;
}
LL c(LL n,LL m,LL p){
if (m < 0 || m > n) return 0;
return fat(n,p)*inv(fat(m,p),p)%p*inv(fat(n-m,p),p)%p;
}
LL crt(LL *a,LL *m,int n){
LL M = 1,res = 0;
for( int i = 0 ; i < n ; i++ ) M*=m[i];
for( int i = 0 ; i < n ; i++ ){
LL w = M/m[i];
res = (res+qmul(w*inv(w,m[i]),a[i],M))%M;
}
return (res+M)%M;
}
LL Lucas(LL n,LL m,LL p){
return m?Lucas(n/p,m/p,p)*c(n%p,m%p,p)%p:1;
}
int main(){
LL n,m;
LL p[15];
LL a[15];
int T,k;
scanf("%d",&T);
while(T--){
scanf("%lld%lld%d",&n,&m,&k);
for( int i = 0 ; i < k ; i++ ){
scanf("%lld",&p[i]);
}
for( int i = 0 ; i < k ; i++ ){
a[i] = Lucas( n , m , p[i] );
}
printf("%lld\n",crt(a,p,k));
}
return 0;
}