1001:简单的求贡献的题目,分段求解最后求出期望即可
代码:
#include<bits/stdc++.h>
using namespace std;
#define p 1000000007
#define INF 0x3f3f3f3f
#define pi 3.141592654
typedef long long ll;
const int N = 2e5+5;
ll sum[N],inv[N];
ll a[N];
int main(){
inv[1]=1,sum[1] = 1,sum[0] = 0;
for(int i=2;i<=N;i++){
inv[i]=(p-p/i)*inv[p%i]%p;
sum[i]= (sum[i-1] + inv[i])%p;
}
int n,t;scanf("%d",&t);
while(t--){
scanf("%d",&n);
ll ans = 0,cnt = n,tem = sum[n];
for(int i =1 ; i<= n ; i++){
scanf("%lld",&a[i]);
if(i > 1){
tem = (tem + sum[n-i+1] - sum[i-1]+ p)%p;
}
ans = (a[i] * tem %p + ans )%p;
}
ans = (ans*inv[n]%p)*inv[n+1]%p *2 %p;
printf("%lld\n",ans);
}
return 0;
}
1002:暴力,注意开ll
队友代码:
#include<bits/stdc++.h>
using namespace std;
typedef long long ll;
char ch[101];
char sh[101];
char mh[101];
int main(){
while(scanf("%s",ch+1)!=EOF){
int t=strlen(ch+1);
int ma=-5;
for(int i=1;i<=t;i++){
char c=ch[i];
if(c>='0'&&c<='9')
c-='0';
if(c>='A'&&c<='F')
c=c-'A'+10;
if(c>=0&&c<=15)
ma=max(ma,(int)c);
}
int k=-1;
// printf("ma=%d\n",ma);
for(ll i=max(ma+1,2);i<=16;i++){
ll shu1=0,f=0,q=-1,shu2=0,shu3=0;
for(int j=1;j<=t;j++){
char c=ch[j];
if(c>='0'&&c<='9')
c-='0';
else if(c>='A'&&c<='F')
c=c-'A'+10;
else if(c=='+')
q=1;
else if(c=='-')
q=2;
else if(c=='*')
q=3;
else if(c=='/')
q=4;
if(q!=-1&&f==0){
f=1;
continue;
}
if(c=='='){
f=2;
continue;
}
ll y=c;
if(f==0)
shu1=shu1*i+y;
else if(f==1){
shu2=shu2*i+y;
}
else if(f==2){
shu3=shu3*i+y;
}
}
// printf("i=%d,shu1=%lld,shu2=%lld,shu3=%lld,q=%lld\n",i,shu1,shu2,shu3,q);
if(q==1){
if(shu1+shu2==shu3){
k=i;
break;
}
}
if(q==2){
if(shu1-shu2==shu3){
k=i;
break;
}
}
if(q==3){
if(shu1*shu2==shu3){
k=i;
break;
}
}
if(q==4){
if(shu1/shu2==shu3&&shu1%shu2==0){
k=i;
break;
}
}
}
printf("%d\n",k);
}
}
1005
题意:给一个序列为1145141919的无限循环串,已知一个N,输出最小的前n位数,在前n位数中任意的加上()+ *使得前n位数构成的式子值为N
思路:
代码:
/// dp[i][j][v1+v2]=dp[i][mid][v1]与dp[mid+1][j][v2]。
/// dp[i][j][v1"v2]=dp[i][mid][v1]与dp[mid+1][j][v2]dp[i][j][v1"v2]=dp[i][mid][v1]与dp[mid+1][j][v2]。
#include <bits/stdc++.h>
using namespace std;
typedef long long ll;
const int N = 5005;
int num[15] = {0,1,1,4,5,1,4,1,9,1,9,1,1,4};
int dp[13][13][N];///dp[i][j][val]表示val在i到j区间可以生成
int ans[N],t,n;
int main(){
for(int i = 1 ; i <= 12 ;i++){
int tem = 0;
for(int j = i ; j <= 12;j++){
tem = tem * 10 + num[j];///加括号可以形成的数
if(tem < N) dp[i][j][tem] = 1;
else break;
}
}
for(int l = 11 ; l >= 1 ; l--){///需要从后往前d,从前往后会造成数值缺失,因为从前往后第一遍扫过去的话,i=1时后面相当于只加了括号,没有进行+*操作
for(int r = l+1 ; r <= 12 ; r++){
for(int mid = l; mid < r ; mid++)
for(int tem = 1; tem <= 5000 ; tem ++){
if(!dp[l][mid][tem]) continue;///区间[l,mid]无法构成数字tem
for(int val = 1 ; val <= 5000 ; val++){
if(!dp[mid+1][r][val]) continue;///区间[mid+1,r]无法构成数字val
if(val + tem < N) dp[l][r][val+tem] = 1;
if(val * tem < N) dp[l][r][val*tem] = 1;
}
}
}
}
for(int i = 12 ; i >= 1 ; i--)
for(int val = 1 ; val <= 5000 ;val ++)
if(dp[1][i][val]) ans[val] = i;
int t;scanf("%d",&t);
while(t --){
scanf("%d",&n);
if(ans[n] > 0) printf("%d\n",ans[n]);
else printf("-1\n");
}
return 0;
}
1006
思路:
队友代码:
/*
* @Author: Admin
* @Date: 2020-08-06 13:12:38
* @Last Modified by: Admin
* @Last Modified time: 2020-08-06 14:21:06
*/
#include <bits/stdc++.h>
using namespace std;
#define pb push_back
#define mp make_pair
#define fi first
#define se second
typedef long long ll;
typedef unsigned long long ull;
typedef pair<int, int> PII;
typedef pair<ll, ll> pll;
const int mod = 1e9 + 7;
const int N = 1e5 + 10;
const int INF = 0x3f3f3f3f;
ll qpow(ll base, ll n){ll ans = 1; while (n){if (n & 1) ans = ans * base % mod; base = base * base % mod; n >>= 1;} return ans;}
ll gcd(ll a, ll b){return b ? gcd(b, a % b) : a;}
int a[N];
int head[N], ver[N << 1], nex[N << 1], tot;
ll edge[N << 1], siz[N][2], num[2], ans;
void add(int u, int v, ll w) {
ver[++ tot] = v;
edge[tot] = w;
nex[tot] = head[u];
head[u] = tot;
}
void dfs(int u, int fa) {
siz[u][0] = a[u] ^ 1;
siz[u][1] = a[u];
for (int i = head[u]; i; i = nex[i]) {
int v = ver[i];
if (v != fa) {
dfs(v, u);
ll x = 0;
ll w = edge[i];
x = (num[1] - siz[v][1]) * siz[v][0] % mod;
x = (x + (num[0] - siz[v][0]) * siz[v][1] % mod) % mod;
ans = (ans + x * w % mod) % mod;
siz[u][0] += siz[v][0];
siz[u][1] += siz[v][1];
}
}
return ;
}
int main()
{
int t;
cin >> t;
while (t --) {
tot = 0;
ans = 0;
memset(head, 0, sizeof(head));
memset(num, 0, sizeof(num));
int n, m;
scanf("%d %d", &n, &m);
for (int i = 1; i <= n; ++ i) {
scanf("%d", &a[i]);
++ num[a[i]];
}
ll w = 1;
for (int i = 1; i <= m; ++ i) {
int u, v;
scanf("%d %d", &u, &v);
if (i < n) {
w = w * 2 % mod;
add(u, v, w);
add(v, u, w);
}
}
dfs(1, -1);
printf("%lld\n", ans);
}
return 0;
}
1009 结论题,注意ll
题意及思路:
#include <bits/stdc++.h>
using namespace std;
typedef long long ll;
int main(){
int t;scanf("%d",&t);
while(t --){
ll b, x;
scanf("%lld %lld", &b, &x);
if (x == 1) printf("T\n");
else {
if (b > x && b % x == 1) printf("T\n");
else printf("F\n");
}
}
return 0;
}
1010
题意:给一个图,生成树的权值定义为树的所有边求与,问随机生成的生成树的期望。
思路:
代码:
#include<bits/stdc++.h>
using namespace std;
#define mod 998244353
#define INF 0x3f3f3f3f
#define pi 3.141592654
typedef long long ll;
const int N = 2e6+5;
ll qpow(ll base, ll n){
ll ans = 1;
while (n){
if (n & 1)
ans = (ans%mod) * (base % mod) %mod;
base = (base%mod) * (base % mod) %mod;
n >>= 1;
}
return ans;
}
ll f[207][207];
ll gauss (int n) {
ll ans = 1 ;
for (int i = 1; i < n; i ++) {
for (int j = i + 1; j < n; j ++) {
while (f[j][i]) {
ll t = f[i][i] / f[j][i] ;
for (int k = i; k < n; k ++)
f[i][k] = (f[i][k] - t * f[j][k] + mod) % mod ;
swap (f[i], f[j]) ;
ans = -ans ;
}
}
ans = (ans * f[i][i]) % mod ;
}
return (ans + mod) % mod ;
}
ll u[40007],v[40007],w[40007];
int main(){
int t;scanf("%d",&t);
while(t--){
int m,n;
scanf("%d %d",&n,&m);
for(int i = 1 ; i <= m ; i++){
scanf("%lld %lld %lld",&u[i],&v[i],&w[i]);
f[u[i]][u[i]]++ ; f[v[i]][v[i]]++;
f[u[i]][v[i]]-- ; f[v[i]][u[i]]--;
}
ll sum = gauss(n);
// printf("%lld\n",sum);
sum = qpow(sum,mod-2);
ll ans = 0,base = 1;
for(int i = 0 ; i <= 30 ; i++){
memset(f,0,sizeof(f));
for(int j = 1 ; j <= m ; j++){
if(w[j]&base){
f[u[j]][u[j]]++ ; f[v[j]][v[j]]++;
f[u[j]][v[j]]-- ; f[v[j]][u[j]]--;
}
}
ans = (ans + gauss(n)*base%mod) % mod;
base *= 2;
}
ans = ans*sum%mod;
printf("%lld\n",ans);
}
return 0;
}