8.26考总
炸了
T1
质数筛+预处理处理出每个数的答案
#include<bits/stdc++.h>
#define int long long
#define endl "\n"
using namespace std;
const int maxn=4e6+5,mod=1e9+7,inf=1e18;
int read(){int x=0,f=1;char ch=getchar();while(ch<'0'||ch>'9'){if(ch=='-')f=-1;ch=getchar();}while(ch>='0' && ch<='9')x=x*10+ch-'0',ch=getchar();return x*f;}
void write(int x){if(x<0){putchar('-'),x=-x;}if(x>9){write(x/10);}putchar(x%10+'0');return;}
int fpow(int a,int b,int p){if(b==0){return 1;}int res=fpow(a,b/2,p)%p;if(b%2==1){return((res*res)%p*a)%p;}else{return(res*res)%p;}}
int t,n;
bool prime[maxn];
int ans[maxn];
void init(){
for(int i=2;i<=maxn-5;i++){
if(prime[i]==0){
for(int j=i+i;j<=maxn-5;j+=i){
prime[j]=1;
}
}
for(int j=i+i;j<=maxn-5;j+=i){
ans[j]=i;
}
}
}
void solve(){
cin>>n;
if(prime[n]==0){
cout<<1<<endl;
}
else{
cout<<ans[n]<<endl;
}
}
signed main(){
init();
cin>>t;
while(t--){
solve();
}
return 0;
}
T2
观察可发现,其实每一对都是两个质数的倍数,我们求出最大的质数的最大倍数,预处理出来即可
#include<bits/stdc++.h>
#define int long long
#define endl "\n"
using namespace std;
const int maxn=2e4+5,mod=99824353,inf=1e18;
int read(){int x=0,f=1;char ch=getchar();while(ch<'0'||ch>'9'){if(ch=='-')f=-1;ch=getchar();}while(ch>='0' && ch<='9')x=x*10+ch-'0',ch=getchar();return x*f;}
void write(int x){if(x<0){putchar('-'),x=-x;}if(x>9){write(x/10);}putchar(x%10+'0');return;}
int fpow(int a,int b,int p){if(b==0){return 1;}int res=fpow(a,b/2,p)%p;if(b%2==1){return((res*res)%p*a)%p;}else{return(res*res)%p;}}
int t,n;
bool prime[maxn];
int num[maxn];
int ans,dp[maxn];
int cnt=0;
void init(){
prime[1]=prime[0]=1;
for(int i=2;i<=maxn;i++){
if(prime[i]==0){
for(int j=i+i;j<=maxn;j+=i){
prime[j]=1;
}
}
}
}
void solve(){
cin>>n;
ans+=dp[n];
ans%=mod;
}
signed main(){
init();
for(int i=1;i<=10000;i++){
if(prime[i]==0){
num[cnt++]=i;
}
}
cnt--;
for(int i=1;i<=10000;i++){
int sum=0;
for(int j=0;j<=cnt&&num[j]<=i;j++){
int x=i/num[j];
sum+=x*j;
sum%=mod;
}
sum*=2;
sum%=mod;
dp[i]=sum;
}
cin>>t;
while(t--){
solve();
}
cout<<ans;
return 0;
}
T3
考虑DP
状态:dp[i]表示前i个字符的最大答案
答案:dp[n]
方程:dp[i]=dp[i-1]
dp[i]=max(dp[i],dp[i-4]+a)
dp[i]=max(dp[i],dp[i-6]+b)
dp[i]=max(dp[i],dp[i-10]+c)
边界:dp[1-3]=0
#include<bits/stdc++.h>
#define int long long
#define endl "\n"
using namespace std;
const int maxn=1e6+5,mod=1e9+7,inf=1e18;
int read(){int x=0,f=1;char ch=getchar();while(ch<'0'||ch>'9'){if(ch=='-')f=-1;ch=getchar();}while(ch>='0' && ch<='9')x=x*10+ch-'0',ch=getchar();return x*f;}
void write(int x){if(x<0){putchar('-'),x=-x;}if(x>9){write(x/10);}putchar(x%10+'0');return;}
int fpow(int a,int b,int p){if(b==0){return 1;}int res=fpow(a,b/2,p)%p;if(b%2==1){return((res*res)%p*a)%p;}else{return(res*res)%p;}}
int n,a,b,c;
string s;
int dp[maxn];
bool check(int x,string s1){
int len=s1.size();
int cnt=0;
if(x<len){
return 0;
}
for(int i=x-len+1;i<=x;i++){
if(s[i]!=s1[cnt++]){
return 0;
}
}
return 1;
}
void solve(){
cin>>n>>a>>b>>c;
cin>>s;
s=' '+s;
string s1="acwa",s2="acwaac",s3="acwaacwaac";
for(int i=4;i<=n;i++){
dp[i]=dp[i-1];
if(check(i,s1)){
dp[i]=max(dp[i],dp[i-4]+a);
}
if(check(i,s2)){
dp[i]=max(dp[i],dp[i-6]+b);
}
if(check(i,s3)){
dp[i]=max(dp[i],dp[i-10]+c);
}
}
cout<<dp[n]<<endl;
}
signed main(){
solve();
return 0;
}
T4
首先不能最大生成树,因为可以有环
我们判断一下连通块,在一个连通块中,一定有n条边给我们选取
所以我们判断一下连通块的数量和边的数量,再按最小生成树的贪心选取即可
#include<bits/stdc++.h>
#define int long long
#define endl "\n"
using namespace std;
const int maxn=1e6+5,mod=1e9+7,inf=1e18;
int read(){int x=0,f=1;char ch=getchar();while(ch<'0'||ch>'9'){if(ch=='-')f=-1;ch=getchar();}while(ch>='0' && ch<='9')x=x*10+ch-'0',ch=getchar();return x*f;}
void write(int x){if(x<0){putchar('-'),x=-x;}if(x>9){write(x/10);}putchar(x%10+'0');return;}
int fpow(int a,int b,int p){if(b==0){return 1;}int res=fpow(a,b/2,p)%p;if(b%2==1){return((res*res)%p*a)%p;}else{return(res*res)%p;}}
int n,t,m;
string s;
int fa[maxn];
int edge[maxn],node[maxn];
struct Node{
int u,v,w;
}a[maxn];
int find(int x){
if(fa[x]==x){
return x;
}
return fa[x]=find(fa[x]);
}
bool cmp(Node x,Node y){
return x.w>y.w;
}
void solve(){
cin>>n>>m;
for(int i=1;i<=n;i++){
fa[i]=i;
edge[i]=0;
node[i]=1;
}
for(int i=1;i<=m;i++){
cin>>a[i].u>>a[i].v>>a[i].w;
}
sort(a+1,a+m+1,cmp);
int ans=0;
for(int i=1;i<=m;i++){
int u=find(a[i].u);
int v=find(a[i].v);
if(u==v){//在同一个块里面
if(edge[u]<node[u]){//边要够
edge[u]++;
ans+=a[i].w;
}
}
else{
if(edge[u]<node[u]||edge[v]<node[v]){//边的数量必须足够
fa[u]=v;//合并连通块
edge[v]+=edge[u];
node[v]+=node[u];
ans+=a[i].w;
edge[v]++;
}
}
}
cout<<ans<<endl;
}
signed main(){
cin>>t;
while(t--){
solve();
}
return 0;
}
本人(KK_SpongeBob)蒟蒻,写不出好文章,但转载请注明原文链接:https://www.cnblogs.com/OIer-QAQ/p/19059726

浙公网安备 33010602011771号