Pro
Sol
任务安排
读懂题之后果断想到二分,暴力判断就可以水过去。
听说贪心也可以……
#include<iostream>
#include<cstdio>
#include<algorithm>
using namespace std;
struct Node {
int time , end;
bool operator < (const Node &a) const {
return end < a.end;
}
};
Node val[100005];
int n , l , r;
int jud(int x) {
int res = x;
for(int i=1; i<=n; i++) {
if(res+val[i].time>val[i].end)
return 0;
res += val[i].time;
}
return 1;
}
int main() {
freopen("manage.in","r",stdin);
freopen("manage.out","w",stdout);
scanf("%d",&n);
for(int i=1; i<=n; i++)
scanf("%d%d",&val[i].time,&val[i].end);
sort(val+1 , val+n+1);
l = 0;
r = val[n].end;
while(l<=r) {
int mid = (l+r)>>1;
if(jud(mid))
l = mid + 1;
else
r = mid - 1;
}
printf("%d",r);
return 0;
}
小 a 的强迫症
又是组合数……
公式见代码…… 不过预处理阶乘的时候0的位置放1会省去一些麻烦……
#include<iostream>
#include<cstdio>
#define mod 998244353
using namespace std;
long long n , num[100005] , sum = 0 , jc[500005] , ans = 1;
inline long long mypow(long long a , long long b) {
if(!b)
return 1;
long long t = mypow(a , b>>1)%mod;
if(b&1)
return t*t%mod*a%mod;
return t*t%mod;
}
inline long long inv(long long x) {
return mypow(x , mod-2)%mod;
}
inline void init() {
jc[1] = 1;
for(int i=2; i<=sum; i++)
jc[i] = jc[i-1]*i%mod;
}
inline long long C(long long x , long long y) {
return jc[x]*inv(jc[y])%mod*inv(jc[x-y])%mod;
}
int main() {
freopen("qiang.in","r",stdin);
freopen("qiang.out","w",stdout);
scanf("%lld",&n);
for(int i=1; i<=n; i++) {
scanf("%lld",&num[i]);
sum += num[i];
}
init();
for(int i=n; i>=1; i--) {
long long t = C(sum-1,num[i]-1)%mod;
ans = ans*(t==0?1:t)%mod;
sum -= num[i];
}
printf("%lld",ans%mod);
return 0;
}
函数求和
最恶心的一道题…… 我打的暴力线段树 水了20分
正解是:分块+树状数组
暴力线段树
#include<iostream>
#include<cstdio>
using namespace std;
const int L = 100005;
struct Seg {
long long l , r , sum;
};
Seg tree[4*L];
struct Node {
long long l , r;
};
Node q[L];
long long n , data[L] , Q;
void build(long long num , long long l , long long r) {
tree[num].l = l;
tree[num].r = r;
if(l == r) {
tree[num].sum = data[l];
return ;
}
long long mid = (l+r)>>1;
build(num<<1 , l , mid);
build(num<<1|1 , mid+1 , r);
tree[num].sum = tree[num<<1].sum + tree[num<<1|1].sum;
}
void update(long long num , long long aim , long long cnt) {
if(tree[num].l==tree[num].r&&tree[num].l==aim) {
tree[num].sum = cnt;
return ;
}
long long mid = (tree[num].l+tree[num].r)>>1;
if(mid<aim)
update(num<<1|1 , aim , cnt);
else
update(num<<1 , aim , cnt);
tree[num].sum = tree[num<<1].sum + tree[num<<1|1].sum;
}
long long query(long long num , long long l , long long r) {
if(l<=tree[num].l&&r>=tree[num].r)
return tree[num].sum;
long long mid = (tree[num].l+tree[num].r)>>1 , res = 0;
if(l<=mid)
res += query(num<<1 , l , r);
if(r>mid)
res += query(num<<1|1 , l , r);
return res;
}
int main() {
freopen("sum.in","r",stdin);
freopen("sum.out","w",stdout);
scanf("%lld",&n);
for(int i=1; i<=n; i++)
scanf("%lld",&data[i]);
build(1 , 1 , n);
for(int i=1; i<=n; i++)
scanf("%lld%lld",&q[i].l,&q[i].r);
scanf("%lld",&Q);
while(Q--) {
long long pot , x , y;
scanf("%lld%lld%lld",&pot,&x,&y);
if(pot == 1)
update(1 , x , y);
if(pot == 2) {
long long ans = 0;
for(int i=x; i<=y; i++)
ans += query(1 , q[i].l , q[i].r);
printf("%lld\n",ans);
}
}
return 0;
}
分块+树状数组
#include<cstdio>
#include<cstring>
#include<algorithm>
#include<cmath>
using namespace std;
typedef unsigned long long LL;
#define lowbit(x) ((x)&-(x))
int n;
int a[100005];
LL c[100005];
int L[100005],R[100005];
int Q;
int t[405][100005];
int belong[100005];// (i-1)/B+1
LL sum[405];
int B,NUM;
void add(int x,LL d){
while(x<=n){
c[x]+=d;
x+=lowbit(x);
}
}
LL ask(int x){
LL ret=0;
while(x){
ret+=c[x];
x-=lowbit(x);
}
return ret;
}
int main(){
freopen("sum.in","r",stdin);
freopen("sum.out","w",stdout);
scanf("%d",&n);
for(int i=1;i<=n;i++){
scanf("%d",&a[i]);
}
for(int i=1;i<=n;i++){
scanf("%d%d",&L[i],&R[i]);
}
B=sqrt(n)+1;
// printf("#%d\n",B);
NUM=(n-1)/B+1;
for(int i=1;i<=n;i++) belong[i]=(i-1)/B+1;
for(int i=1;i<=n;i++) c[i]=a[i];
for(int i=1;i<=n;i++){
if(i+lowbit(i)<=n){
c[i+lowbit(i)]+=c[i];
}
}
for(int i=1;i<=n;i++){
t[belong[i]][L[i]]++;
t[belong[i]][R[i]+1]--;
}
for(int i=1;i<=NUM;i++){
for(int j=1;j<=n;j++){
t[i][j]+=t[i][j-1];
sum[i]+=t[i][j]*1ULL*a[j];
}
}
scanf("%d",&Q);
while(Q--){
int type,x,y;
scanf("%d%d%d",&type,&x,&y);
if(type==1){
for(int i=1;i<=NUM;i++){
sum[i]-=t[i][x]*1ULL*a[x];
sum[i]+=t[i][x]*1ULL*y;
}
add(x,-a[x]);
a[x]=y;
add(x,a[x]);
}else{
int Ln,Rn;
Ln=belong[x],Rn=belong[y];
LL ans=0;
if(Ln==Rn){
for(int i=x;i<=y;i++){
ans+=ask(R[i])-ask(L[i]-1);
}
}else{
for(int i=Ln+1;i<Rn;i++) ans+=sum[i];
int lim;
lim=Ln*B;
lim=min(lim,y);
for(int i=x;i<=lim;i++){
ans+=ask(R[i])-ask(L[i]-1);
}
lim=(Rn-1)*B+1;
lim=max(lim,x);
for(int i=lim;i<=y;i++){
ans+=ask(R[i])-ask(L[i]-1);
}
}
printf("%llu\n",ans);
}
}
fclose(stdout);
return 0;
}