2019 Multi-University Training Contest 3
Solved | Pro.ID | Title | Ratio(Accepted / Submitted) | 知识点 |
---|---|---|---|---|
1001 | Azshara's deep sea | 6.67%(6/90) | 凸包 | |
已补 | 1002 | Blow up the city | 31.19%(126/404) | 支配树/容斥 |
1003 | Yukikaze and Demons | 16.67%(4/24) | 分治/同余 | |
1004 | Distribution of books | 19.29%(93/482) | dp/平衡树/离散化后权值线段树维护/二分 | |
1005 | Easy Math Problem | 9.30%(4/43) | 杜教筛 | |
1006 | Fansblog | 21.17%(671/3170) | 威尔逊定理 + 质数的密度分布 | |
已补 | 1007 | Find the answer | 11.24%(508/4521) | 线段树 |
1008 | Game | 16.08%(23/143) | 三维莫队 | |
队友已补 | 1009 | K Subsequence | 5.81%(87/1497) | 费用流 |
1010 | Sindar's Art Exhibition | 24.66%(18/73) | 树链剖分 | |
1011 | Squrirrel | 13.86%(46/332) | dfs |
1002
https://www.cnblogs.com/1625--H/p/11286941.html
1006
暴力找小于P的质数Q,然后依次乘逆元
#include <bits/stdc++.h>
using namespace std;
typedef long long ll;
ll mul(ll a,ll b,ll p){
ll res = 0;
for(;b;b>>=1){
if(b & 1)res = (res + a)%p;
a = (a+a)%p;
}
return res;
}
ll pow_mod(ll a,ll b,ll p){
ll res = 1;
for(;b;b>>=1){
if(b & 1)res = mul(res,a,p);
a = mul(a,a,p);
}
return res;
}
bool isP(ll n){
for(ll i=2;i*i<=n;i++){
if(n % i == 0)return false;
}
return true;;
}
int main(){
int T;scanf("%d",&T);
while(T--){
ll q;scanf("%lld",&q);
ll i;
for(i=q-1;;i--){
if(isP(i)){
break;
}
}
//cout<<i<<endl;
ll res = 1;
for(ll j=i+1;j<=q-2;j++){
res = mul(res,pow_mod(j,q-2,q),q);
}
printf("%lld
",res);
}
}
1007
单点修改线段树
#include <bits/stdc++.h>
using namespace std;
const int N = 2e5+10;
typedef long long ll;
ll sum[N];
int Q,w[N],id[N],idx[N];
struct SegTree{
int l,r;
ll sum;
int cnt;
}t[4*N];
bool cmp(int x,int y){
return w[x] < w[y];
}
void build(int p,int l,int r){
t[p].l = l;t[p].r = r;
if(l == r){
t[p].sum = w[id[l]];
t[p].cnt = 1;
return;
}
int mid = l + r >> 1;
build(p*2,l,mid);
build(p*2+1,mid+1,r);
t[p].sum = t[p*2].sum + t[p*2+1].sum;
t[p].cnt = t[p*2].cnt + t[p*2+1].cnt;
}
int query(int p,int mx){
if(t[p].sum <= mx)return t[p].r;
if(t[p].l == t[p].r){
if(t[p].sum <= mx)return t[p].r;
return t[p].l;
}
if(t[p*2].sum > mx)return query(p*2,mx);
return query(p*2+1,mx-t[p*2].sum);
}
int query_num(int p,int l,int r){
if(t[p].l >= l && t[p].r <= r)return t[p].cnt;
int mid = t[p].l + t[p].r >> 1;
int res = 0;
if(mid >= l)res = query_num(p*2,l,r);
if(mid < r)res += query_num(p*2+1,l,r);
return res;
}
void change_val(int p,int pos,int val){
if(t[p].l == t[p].r && t[p].l == pos){
t[p].sum = 0;return;
}
int mid = t[p].l + t[p].r >> 1;
if(mid >= pos)change_val(p*2,pos,val);
if(mid < pos)change_val(p*2+1,pos,val);
t[p].sum = t[p*2].sum + t[p*2+1].sum;
}
void change_cnt(int p,int pos){
if(t[p].l == pos && t[p].r == pos){
t[p].cnt = 0;
return;
}
int mid = t[p].l + t[p].r >> 1;
if(mid >= pos)change_cnt(p*2,pos);
if(mid < pos)change_cnt(p*2+1,pos);
t[p].cnt = t[p*2].cnt + t[p*2+1].cnt;
}
int ans[N],n,m;
int main(){
scanf("%d",&Q);
while(Q--){
scanf("%d%d",&n,&m);
for(int i=1;i<=n;i++){
scanf("%d",&w[i]);
id[i] = i;
}
sort(id+1,id+1+n,cmp);
for(int i=1;i<=n;i++)idx[id[i]] = i;
for(int i=1;i<=n;i++)sum[i] = sum[i-1] + w[id[i]];
build(1,1,n);
for(int i=n;i>=1;i--){
change_val(1,idx[i],w[i]);
change_cnt(1,idx[i]);
int mx = m - w[i];
int pos = query(1,mx)-1;
int cnt = query_num(1,1,pos);
ans[i] = i - cnt - 1;
}
for(int i=1;i<=n;i++){
printf("%d ",ans[i]);
}
puts("");
}
return 0;
}