题目链接
题意:
给一个包含只包含大写字母的字符串,找有多少个子串包含 k k k 个 R R R 字符且不包含 P P P 字符
题解:
不包括 P P P 就分段来计算
至少包含 k k k 个 R R R
贡献就等于这个位置 第前 k 个 R R R 位置
#include
#define int long long
using namespace std;
const int N=2e5+5;
int a[N], p[N];
signed main() {
int n, k; cin>>n>>k;
string s; cin>>s;
s=s+"P";
int cnt=0;
a[0]=-1;
for (int i=0; i<=n; i++) {
if(s[i]=='P') a[++cnt]=i;
}
int ans=0;
for(int j=1; j<=cnt; j++) {
int cntt=0;
p[0]=0;
for (int i=a[j-1]+1; i<a[j]; i++) {
if (s[i]=='R') p[++cntt]=i+1-a[j-1]-1;
if(cntt>=k) ans+=p[cntt-k+1];
}
}
cout<<ans<<endl;
return 0;
}
题解:
所能表示的某进制的最小值的某进制就是该串里的最大的数字+1,不然那个数不可能出现
题目要求单点修改和区间查询
那就是最简单的求最大值和求和的线段树板子
求和的线段树是存了2-10进制棵每一位的数字 * 该位权值
比如10进制树 123存的是1 * 10 * 10 ------- 2*10 -------3
求和出来还要除与多的权值 取[1,2] ,答案等于120/10
#include
#define int long long
#define ll long long
using namespace std;
const int N=1e5+5;
const int M=1e9+7;
int a[N];
int b[13][N];
int n, q;
int p[13][N];
int maxx[4*N];
int sum[13][4*N];
ll ksm(ll a,ll p){ll res=1;while(p){if(p&1){res=res*a%M;}a=a*a%M;p>>=1;}return res;}
void pushup(int id) {
maxx[id] = max(maxx[id << 1], maxx[id << 1 | 1]);
}
void build(int id, int l, int r) {
if (l == r) {
maxx[id] = a[l];
return;
}
int mid = (l + r) >> 1;
build(id << 1, l, mid);
build(id << 1 | 1, mid + 1, r);
pushup(id);
}
void update(int id, int l, int r, int x, int v) {
if (l == r) {
maxx[id] = v;
return;
}
int mid = (l + r) >> 1;
if (x <= mid) {
update(id << 1, l, mid, x, v);
} else {
update(id << 1 | 1, mid + 1, r, x, v);
}
pushup(id);
}
int query(int id, int l, int r, int x, int y) {
if(x<=l&&r<=y) {
return maxx[id];
}
int mid=(l+r)>>1;
int ans=0;
if(x<=mid) {
ans=max(ans, query(id<<1, l, mid, x, y));
}
if(y>mid) {
ans=max(ans, query(id<<1|1, mid+1, r, x, y));
}
return ans;
}
void pushup1(int id, int jin) {
sum[jin][id] = (sum[jin][id << 1]+sum[jin][id << 1 | 1])%M;
}
void build1(int id, int l, int r, int jin) {
if (l == r) {
sum[jin][id] = b[jin][l]%M;
return;
}
int mid = (l + r) >> 1;
build1(id << 1, l, mid, jin);
build1(id << 1 | 1, mid + 1, r, jin);
pushup1(id, jin);
}
void update1(int id, int l, int r, int x, int v, int jin) {
if (l == r) {
sum[jin][id] = v%M;
return;
}
int mid = (l + r) >> 1;
if (x <= mid) {
update1(id << 1, l, mid, x, v,jin);
} else {
update1(id << 1 | 1, mid + 1, r, x, v,jin);
}
pushup1(id, jin);
}
int query1(int id, int l, int r, int x, int y,int jin) {
if(x<=l&&r<=y) {
return sum[jin][id]%M;
}
int mid=(l+r)>>1;
int ans=0;
if(x<=mid) {
ans=ans%M+query1(id<<1, l, mid, x, y,jin)%M;
}
if(y>mid) {
ans=ans%M+query1(id<<1|1, mid+1, r, x, y,jin)%M;
}
ans%=M;
return ans;
}
signed main() {
cin>>n>>q;
string s;
cin>>s;
s='.'+s;
for(int i=n; i>=1; i--) {
a[i]=(s[i]-'0');
}
for(int i=n; i>=1; i--) {
for(int j=2; j<=10; j++) {
b[j][i]=a[i]*ksm(j, n-i)%M;
//cout<
}
}
build(1, 1, n);
for(int i=2; i<=10; i++) build1(1, 1, n, i);
//cout<<"$$$"<
while(q--) {
int op, x, y;
cin>>op>>x>>y;
if(op==1) {
update(1, 1, n, x, y);
for(int i=2; i<=10; i++) update1(1, 1, n, x, y*ksm(i, n-x), i);
}else {
int dang=query(1, 1, n, x, y);
if(dang==0) cout<<0<<endl;
else {
dang++;
cout<<query1(1,1,n,x, y,dang)%M*ksm(ksm(dang, n-y), M-2)%M<<endl;//逆元
}
}
}
return 0;
}
题解:
前缀和求覆盖次数
#include
#define int long long
using namespace std;
const int N=2e5+5;
int a[N], b[N], c[N];
signed main() {
int n, t;
cin>>n>>t;
string s;
cin>>s;
s='.'+s;
for(int i=1; i<=n; i++) {
int x; cin>>x;
if(s[i]=='B') b[x]++, b[x+t]--;//x和x+t-1+1
else c[x]++, c[x+t]--;
}
for(int i=1; i<=N; i++) {
b[i]+=b[i-1];
c[i]+=c[i-1];
//cout<
}
int ans=0;
for(int i=1; i<=N; i++) {
if(b[i]&&!c[i]) ans++;
}
cout<<ans<<endl;
return 0;
}
题目链接
题意:
题解:
求点到线段的最短距离板子
#include
#define int long long
#define ll long long
using namespace std;
const int N=2e5+5;
const int M=1e9+7;
double dis(double xx, double yy, double x1, double y2) {
return sqrt((xx-x1)*(xx-x1)+(yy-y2)*(yy-y2));
}
double Pd(double x, double y, double x1, double y1, double x2, double y2){
double cross = (x2 - x1) * (x - x1) + (y2 - y1) * (y - y1);
if (cross <= 0) return sqrt((x - x1) * (x - x1) + (y - y1) * (y - y1));
double d2 = (x2 - x1) * (x2 - x1) + (y2 - y1) * (y2 - y1);
if (cross >= d2) return sqrt((x - x2) * (x - x2) + (y - y2) * (y - y2));
double r = cross / d2;
double px = x1 + (x2 - x1) * r;
double py = y1 + (y2 - y1) * r;
return sqrt((x - px) * (x - px) + (py - y) * (py - y));
}
signed main() {
int n;
cin>>n;
double x0, y0, X, Y;
cin>>x0>>y0>>X>>Y;
double minn=dis(x0,y0,X,Y);
for(int i=1; i<=n; i++) {
double x, y;
cin>>x>>y;
minn=min(minn, Pd(X, Y, x0,y0, x0+x, y0+y));
x0+=x;
y0+=y;
}
cout<<fixed<<setprecision(8)<<minn<<endl;
return 0;
}
题目链接
题意:
那个函数就是求本身
题解:
要开longlong
#include
#define int long long
using namespace std;
const int N=2e5+5;
signed main() {
int x;
cin>>x;
cout<<x<<endl;
return 0;
}
题目链接
题意:
模拟
题解:
模拟
#include
#define int long long
using namespace std;
const int N=2e5+5;
int a[N], b[N], c[N];
map<char, int> mp;
signed main() {
string pp="CDEFGAB";
for(int i=0; i<pp.size(); i++) mp[pp[i]]=i+1;
string s;
cin>>s;
int n=s.size();
int p=0;//呜呜在里面定义忘记赋值 找了好久bug
for(int i=0; i<n; i++) {
if(s[i]=='<') p++;
else if(s[i]=='>') p--;
else {
cout<<mp[s[i]];
if(p==0) continue;
else if(p>0) {
for(int j=1; j<=p; j++) cout<<'.';
}else for(int j=1; j<=-p; j++) cout<<'*';
}
}
cout<<endl;
return 0;
}
题目链接
题意:
求这个数组的所有 非空子序列 的最大值*最小值的乘积是多少?
1e5
题解:
先排序
若它作为一个字序列的最小值,后面的 n − i n-i n−i 个数随意,也就是有 2 的 n − i 2的n-i 2的n−i 次方 个机会作为最小值,同样的,有 2 的 i − 1 2的 i-1 2的i−1次方 个机会作为最小值,那这个数产生的贡献就是
幂次取模的话取 M o d − 1 Mod-1 Mod−1
证明如下
#include
#define int long long
#define ll long long
using namespace std;
const int N=2e5+5;
const int M=1e9+7;
const int MM=1e9+6;
int a[N], b[N];
int dp[1005][1005];
ll ksm(ll a,ll p){ll res=1;while(p){if(p&1){res=res*a%M;}a=a*a%M;p>>=1;}return res%M;}
ll ksmm(ll a,ll p){ll res=1;while(p){if(p&1){res=res*a%MM;}a=a*a%MM;p>>=1;}return res%MM;}
signed main() {
int n;
cin>>n;
for(int i=1; i<=n; i++) cin>>a[i];
sort(a+1, a+1+n);
int ans=1;
for(int i=1; i<=n; i++) {
int b=ksmm(2, i-1)+ksmm(2, n-i);
ans=ans%M*ksm(a[i], b)%M;
ans%=M;
}
cout<<ans%M<<endl;
return 0;
}
题目链接
题意:
题解:
就是把距离当成体对角线来算体积
因为小紫肯定在正方体中间
#include
#define ihnt long long
using namespace std;
const int N=2e5+5;
signed main() {
double x;
cin>>x;
cout<<fixed<<setprecision(7)<<x/sqrt(3)*2*x/sqrt(3)*2*x/sqrt(3)*2<<endl;
return 0;
}
题目链接
题意
题解
d p [ i ] [ j ] dp[i][j] dp[i][j] 代表轮到第 i i i张卡时候的质量% k = = j k==j k==j的最大值
转移方程
i n t p = ( j − a [ i ] + k ) int p=(j-a[i]+k) intp=(j−a[i]+k)%k
d p [ j ] [ i ] = m a x ( d p [ j ] [ i − 1 ] , d p [ j ] [ i ] ) ; dp[j][i]=max(dp[j][i-1], dp[j][i]); dp[j][i]=max(dp[j][i−1],dp[j][i]);不取当前牌
d p [ j ] [ i ] = m a x ( d p [ p ] [ i − 1 ] + b [ i ] , d p [ j ] [ i ] ) ; dp[j][i]=max(dp[p][i-1]+b[i], dp[j][i]); dp[j][i]=max(dp[p][i−1]+b[i],dp[j][i]); 取当前牌
#include
#define int long long
#define ll long long
using namespace std;
const int N=2e5+5;
const int M=1e9+7;
int a[N], b[N];
int dp[1005][1005];
signed main() {
int n, k;
cin>>n>>k;
for(int i=1; i<=n; i++) {
cin>>a[i]>>b[i];
a[i]%=k;
}
for(int i=0; i<=n; i++)for(int j=0; j<=k; j++) dp[i][j]=-1e18;
dp[0][0]=0;
for(int i=1; i<=n; i++) {
for(int j=k-1; j>=0; j--) {
int p=(j-a[i]+k)%k;
dp[j][i]=max(dp[j][i-1], dp[j][i]);
dp[j][i]=max(dp[p][i-1]+b[i], dp[j][i]);
}
}
int maxx=dp[0][n];
if(maxx<=0) cout<<-1<<endl;
else cout<<maxx<<endl;
return 0;
}
题目链接
题意:
#include
#define int long long
#define ll long long
using namespace std;
const int N=2e5+5;
const int M=1e9+7;
int p[N];
bool check[N],vis[N];
int n, m;
void init() {
int t;
check[1]=true;
for(int i=2;i<=n;i++){
if(!check[i])p[++p[0]]=i;
for(int j=1;j<=p[0];j++){
t=i*p[j];
if(t>n)break;
check[t]=true;
if(i%p[j]==0)break;
}
}
}
ll ksm(ll a,ll p){ll res=1;while(p){if(p&1){res=res*a%M;}a=a*a%M;p>>=1;}return res;}
int mp[N];
signed main() {
n=30001;
init();
int l, r;
cin>>l>>r;
bool q=0;
for(int i=l; i<=r; i++) {
int num=i;
int m=0;
for(int j=1; j<=p[0]; j++) {
while(num%p[j]==0) {
num/=p[j];
m++;
}
}
if(m>=2) q=1;
else continue;
num=i;
for(int j=1; j<=p[0]; j++) {
int sum=0;
while(num%p[j]==0) {
num/=p[j];
sum++;
}
mp[p[j]]=max(sum, mp[p[j]]);
}
}
if(!q) {
cout<<-1<<endl;
return 0;
}
int ans=1;
for(int i=1; i<=p[0]; i++) {
ans=ans*ksm(p[i], mp[p[i]])%M;
ans%=M;
}
cout<<ans<<endl;
return 0;
}
题目链接
题意:
题解:
101变成101101
就等于乘(2的幂次+1)一定是倍数且1的个数不同
#include
#define int long long
using namespace std;
const int N=2e5+5;
signed main() {
int x;
cin>>x;
string s;
while(x) {
s=char('0'+x%2)+s;
x/=2;
}
s=s+s;
int ans=0;
int p=1;
for(int i=0; i<s.size(); i++) {
ans=ans*2+(s[i]-'0');
}
cout<<ans<<endl;
return 0;
}
题目链接
Qwq