T1
题意:
对于给定的数组\(a\),存在多少个四元组\((b_{1},b_{2},b_{3},b_{4})(1\le b_{1}<b_{2}<b_{3}<b_{4}\le n)\),使得\(a_{b_{1}}\) \(xor\) \(a_{b_{2}}\) \(xor\) \(a_{b_{3}}\) \(xor\) \(a_{b_{4}}=0\)。
思路:
开桶维护\(a_{b_{1}}\) \(xor\) \(a_{b_{2}}\),然后将\(a_{b_{3}}\) \(xor\) \(a_{b_{4}}\)的个数加进答案。
代码:
#include<iostream>
using namespace std;
int kd(){
int x=0,f=1;
char a=getchar();
while(a<'0'||a>'9'){
if(a=='-'){
f=-1;
}
a=getchar();
}
while(a>='0'&&a<='9'){
x=x*10+a-'0';
a=getchar();
}
return x*f;
}
int n;
int a[5010];
long long qian[2000010],hou[2000010];
int main(){
n=kd();
for(int i=1;i<=n;i++){
a[i]=kd();
}
long long ans=0;
for(int i=1;i<=n;i++){
for(int j=i+1;j<=n;j++){
ans=(ans+qian[a[i]^a[j]]);
}
for(int j=i-1;j>=1;j--){
qian[a[i]^a[j]]++;
}
}
cout<<ans;
return 0;
}
T2
题意:
给定一张\(k\)进制乘法表,问每个数字代表什么。
思路:
\(0\times (k-1)=(0)(0)\)
\(1\times (k-1)=(0)(k-1)\)
\(2\times (k-1)=(1)(k-2)\)
……
\((k-1)\times (k-1)=(k-2)(1)\)
通过这个规律,就可以解决这个问题。
代码:
#include<iostream>
using namespace std;
int kd(){
int x=0,f=1;
char a=getchar();
while(a<'0'||a>'9'){
if(a=='-'){
f=-1;
}
a=getchar();
}
while(a>='0'&&a<='9'){
x=x*10+a-'0';
a=getchar();
}
return x*f;
}
int n;
int tong[2010];
int m[2010][2010];
int ans[2010];
int f[2010];
int biao[2010];
int main(){
cin>>n;
for(int i=0;i<n;i++){
ans[i]=-1;
for(int j=0;j<n;j++){
int a,b;
a=kd();b=kd();
m[i][j]=a;
tong[a]++;
}
}
for(int j=0;j<n;j++){
int p=0;
for(int i=0;i<n;i++){
if(m[i][j]!=j){
p=1;
break;
}
}
if(p==0){
ans[j]=0;
f[0]=j;
}
}
for(int i=0;i<n;i++){
if(tong[i]==0){
ans[i]=n-1;
f[n-1]=i;
}
}
for(int i=0;i<n;i++){
if(i!=f[0]){
biao[m[i][f[n-1]]]=i;
}
}
for(int i=1;i<n;i++){
f[i]=biao[f[i-1]];
ans[biao[f[i-1]]]=i;
}
for(int i=0;i<n;i++){
cout<<ans[i]<<" ";
}
return 0;
}
T3
题意:
给定\(n(n\le40)\)个数,问所有子集中的和十进制下数位上4的个数的总数。
思路:
考虑折半搜索,对其中一个数组基数排序,枚举另一个数组,二分查找使每一位为4的个数。
代码:
#include<iostream>
#include<algorithm>
using namespace std;
int kd(){
int x=0,f=1;
char a=getchar();
while(a<'0'||a>'9'){
if(a=='-'){
f=-1;
}
a=getchar();
}
while(a>='0'&&a<='9'){
x=x*10+a-'0';
a=getchar();
}
return x*f;
}
int n;
int a[50];
long long ans;
long long tonga[1100000];
long long tongb[1100000];
long long ta[1100000];
long long tb[1100000];
void dfs1(int i,long long tot){
if(i>n/2){
ta[++ta[0]]=tot;
return ;
}
dfs1(i+1,tot+a[i]);
dfs1(i+1,tot);
}
void dfs2(int i,long long tot){
if(i>n){
tb[++tb[0]]=tot;
return ;
}
dfs2(i+1,tot+a[i]);
dfs2(i+1,tot);
}
bool cmp(long long x,long long y){
return x<y;
}
bool cnp(long long x,long long y){
return x>y;
}
int main(){
n=kd();
for(int i=1;i<=n;i++){
a[i]=kd();
}
dfs1(1,0);
dfs2(n/2+1,0);
long long t=1;
for(int k=1;k<=3;k++){
t*=10;
for(int i=1;i<=ta[0];i++){
tonga[ta[i]%t]++;
}
for(int i=1;i<=tb[0];i++){
tongb[tb[i]%t]++;
}
for(int i=0;i<=t-1;i++){
for(int j=0;j<=t-1;j++){
if((i+j)%t/(t/10)==4){
ans+=tonga[i]*tongb[j];
}
}
}
for(int i=0;i<=t-1;i++){
tonga[i]=0;
tongb[i]=0;
}
}
for(int k=4;k<=9;k++){
t*=10;
tonga[0]=0;
tongb[0]=0;
for(int i=1;i<=ta[0];i++){
tonga[++tonga[0]]=ta[i]%t;
}
for(int i=1;i<=tb[0];i++){
tongb[++tongb[0]]=tb[i]%t;
}
sort(tonga+1,tonga+tonga[0]+1,cmp);
sort(tongb+1,tongb+tongb[0]+1,cnp);
int j=1;
for(int i=1;i<=tonga[0];i++){
while(tongb[j]+tonga[i]>=t/10*15&&j<=tongb[0]){
ans+=i-1;
j++;
}
}
for(;j<=tongb[0];j++){
ans+=tonga[0];
}
j=1;
for(int i=1;i<=tonga[0];i++){
while(tongb[j]+tonga[i]>=t/10*14&&j<=tongb[0]){
ans-=i-1;
j++;
}
}
for(;j<=tongb[0];j++){
ans-=tonga[0];
}
j=1;
for(int i=1;i<=tonga[0];i++){
while(tongb[j]+tonga[i]>=t/10*5&&j<=tongb[0]){
ans+=i-1;
j++;
}
}
for(;j<=tongb[0];j++){
ans+=tonga[0];
}
j=1;
for(int i=1;i<=tonga[0];i++){
while(tongb[j]+tonga[i]>=t/10*4&&j<=tongb[0]){
ans-=i-1;
j++;
}
}
for(;j<=tongb[0];j++){
ans-=tonga[0];
}
}
cout<<ans;
return 0;
}
T4
题意:
将数组\(a\)重排,求前\(k\)大的\(\sum_{i=1}^{n-1} |a_{i}-a_{i+1}|\)的值和方案数,方案数对\(1e9+7\)取模。
思路:
将\(a_{i}\)从小到大排序,插入序列,将序列分为几个块,新加进来的\(a_{i}\)可以1.组成一个新块,最终权值减\(2\times a_{i}\);2.加进一个块的一端,最终权值不变;3.合并两个块,最终权值加\(2\times a_{i}\);4.放在最边缘,最终权值减\(a_{i}\);5.链接边缘和一个块,最终权值加\(a_{i}\)。
\(fin_{i,j,0/1/2,k}\)表示放了\(i\)个数,有\(j\)个块,有\(0/1/2\)个边缘被放了,的第\(k\)大的值。
\(sch_{i,j,0/1/2,k}\)表示其对应的方案数。
代码:
#include<iostream>
#include<algorithm>
#define mod 1000000007
#define int long long
using namespace std;
int n,k;
int a[610];
struct node{
int fin;
int sch;
}f[2][610][3][110];
bool cmp(int x,int y){
return x<y;
}
bool cnp(node x,node y){
return x.fin>y.fin;
}
int t;
signed main(){
cin>>n>>k;
for(int i=1;i<=n;i++){
cin>>a[i];
}
sort(a+1,a+n+1,cmp);
f[0][0][0][1].sch=1;
for(int i=1;i<=n;i++){
t^=1;
for(int j=1;j<=i;j++){
for(int l=0;l<=2;l++){
int cnt=0;
for(int h=1;h<=k;h++){
if(j>min(i-1,1ll)&&f[t^1][j-1][l][h].sch!=-1){
cnt++;
f[t][j][l][cnt].fin=f[t^1][j-1][l][h].fin-a[i]*2;
f[t][j][l][cnt].sch=f[t^1][j-1][l][h].sch*(j-l)%mod;
}
if(f[t^1][j][l][h].sch!=-1){
cnt++;
f[t][j][l][cnt].fin=f[t^1][j][l][h].fin;
f[t][j][l][cnt].sch=f[t^1][j][l][h].sch*(2*j-l)%mod;
}
if(f[t^1][j+1][l][h].sch!=-1){
cnt++;
f[t][j][l][cnt].fin=f[t^1][j+1][l][h].fin+a[i]*2;
f[t][j][l][cnt].sch=f[t^1][j+1][l][h].sch*(j)%mod;
}
if(l>0){
if(f[t^1][j][l-1][h].sch!=-1){
cnt++;
f[t][j][l][cnt].fin=f[t^1][j][l-1][h].fin+a[i];
f[t][j][l][cnt].sch=f[t^1][j][l-1][h].sch*(3-l)%mod;
}
if(f[t^1][j-1][l-1][h].sch!=-1&&j>min(i-1,1ll)){
cnt++;
f[t][j][l][cnt].fin=f[t^1][j-1][l-1][h].fin-a[i];
f[t][j][l][cnt].sch=f[t^1][j-1][l-1][h].sch*(3-l)%mod;
}
}
}
sort(f[t][j][l]+1,f[t][j][l]+cnt+1,cnp);
int w=1;
for(int h=1;h<=k;h++){
while(w<=cnt&&f[t][j][l][w].sch<=0){
w++;
}
if(w>cnt){
f[t][j][l][h].fin=-1;
f[t][j][l][h].sch=-1;
continue;
}
f[t][j][l][h].fin=f[t][j][l][w].fin;
f[t][j][l][h].sch=f[t][j][l][w].sch;
w++;
while(w<=cnt&&f[t][j][l][h].fin==f[t][j][l][w].fin){
f[t][j][l][h].sch=(f[t][j][l][h].sch+f[t][j][l][w].sch)%mod;
w++;
}
}
}
}
}
for(int h=1;h<=k;h++){
cout<<f[t][1][2][h].fin<<" "<<f[t][1][2][h].sch<<endl;
}
return 0;
}
标签:24,cnt,sch,int,++,2023.2,&&,fin,模拟
From: https://www.cnblogs.com/z-2-we/p/17162250.html