可惜沒打成這場,要不然應該可以AK的/kk/fad
E
有一個數列,滿足,現在對於給定的,求這個數列的中位數可能有多少種不同的情況
這道題還是比較好想的,一個點能否成爲中位數,就是他左邊和右邊的的數量相同
我們對於左端點和右端點進行排序,就可以找到他的範圍了
注意對於奇數和偶數進行分類討論
#include <bits/stdc++.h>
using namespace std;
# define Rep(i,a,b) for(int i=a;i<=b;i++)
# define _Rep(i,a,b) for(int i=a;i>=b;i--)
# define RepG(i,u) for(int i=head[u];~i;i=e[i].next)
typedef long long ll;
const int N=2e5+5;
template<typename T> void read(T &x){
x=0;int f=1;
char c=getchar();
for(;!isdigit(c);c=getchar())if(c=='-')f=-1;
for(;isdigit(c);c=getchar())x=(x<<1)+(x<<3)+c-'0';
x*=f;
}
int n;
int l[N],r[N];
int p,q;
int main()
{
read(n);
Rep(i,1,n)read(l[i]),read(r[i]);
sort(l+1,l+n+1);
sort(r+1,r+n+1);
if(n%2==0){
p=l[n>>1]+l[(n>>1)+1],q=r[n>>1]+r[(n>>1)+1];
printf("%d\n",q-p+1);
}
else{
p=l[n+1>>1],q=r[n+1>>1];
printf("%d\n",q-p+1);
}
return 0;
}
F
現在有一個長度爲的序列
設全集,爲的一個非空子集,現在定義表示不同的的非空子集的個數,是的
現在對於每一個,求
首先考慮如果的時候怎麼求
非常的簡單,就是一個非常樸素的揹包
我們用表示前個數,和爲的方案數,那麼有
顯然我們需要更改一下狀態:表示由前個數組成的所有集合中,選出和爲的方案數總和
那麼怎麼求出每一個集合的方法呢?
我們把最開始的轉移看成兩部分
- 從轉移過來,此時我們求和時不選,那麼也就是說,不管我們的集合裏面選不選,這個方案一直都在,所以這時候的轉移量應該是
- 從,這個時候我們必須選擇,所以他應該算到答案的集合裏面必須有,所以方案數不變
那麼我們的轉移就變成了
初值
答案
然後就輕鬆通過了qwq
#include <bits/stdc++.h>
using namespace std;
# define Rep(i,a,b) for(int i=a;i<=b;i++)
# define _Rep(i,a,b) for(int i=a;i>=b;i--)
# define RepG(i,u) for(int i=head[u];~i;i=e[i].next)
typedef long long ll;
const int N=3005;
const int mod=998244353;
template<typename T> void read(T &x){
x=0;int f=1;
char c=getchar();
for(;!isdigit(c);c=getchar())if(c=='-')f=-1;
for(;isdigit(c);c=getchar())x=(x<<1)+(x<<3)+c-'0';
x*=f;
}
int n,m;
int a[N];
int f[N][N];
int mi[N];
int main()
{
read(n),read(m);
Rep(i,1,n)read(a[i]);
f[0][0]=1;
Rep(i,1,n){
Rep(j,0,m){
f[i][j]=f[i-1][j]*2%mod;
if(j>=a[i])f[i][j]+=f[i-1][j-a[i]],f[i][j]%=mod;
}
}
printf("%d\n",f[n][m]);
return 0;
}