题目来源:https://ac.nowcoder.com/acm/contest/3002
实力只有八题,觉得发挥的比较好了。(也许今晚会补题 也许明天,保证不咕~)。
upd: 更新完毕 ~ 请放心食用~
假如一边平行x轴,那分两种情况 此边长为2,此边长为1
平行y轴同理,最后发现这两种情况之和多算了 一边平行x轴另一边平行y轴的情况
减去就完事了(多出来的就是 1x2的矩形数量的4倍)
#include
#include
#include
#include
#include
#include
#include
#include
#include
#include
#include
#define ls k<<1,l,mid
#define rs k<<1|1,mid+1,r
#define mp(x,y) make_pair(x,y)
#define r(x) read(x)
#define rrr(x,y,z) read(x);read(y);read(z)
#define FOR(i,l,r) for(int i=l;i<=r;i++)
using namespace std;
typedef long long LL;
typedef pair<int,int> pt;
const int N=1e6+5;
const int M=2e3+5;
const int INF=0x7fffffff;
const int mod=1e9+7;
const double eps=1e-8;
const double pi=acos(-1);
LL n,m;
template<class T>
inline void read(T &x)
{
char c; x=1;
while((c=getchar())<'0'||c>'9') if(c=='-') x=-1;
T res=c-'0';
while((c=getchar())>='0'&&c<='9') res=res*10+c-'0';
x*=res;
}
int main()
{
r(n); r(m);
LL ans=0;
//平行x轴 长为2
ans=(ans+2ll*(m-2)%mod*m%mod)%mod; //边上的两个
if(n>2) ans=(ans+2ll*(n-2)%mod*(m-2)%mod*m%mod)%mod;
//长为1
ans=(ans+1ll*min(4ll,2ll*(n-2))*(m-1)%mod*m%mod)%mod;
if(n>4) ans=(ans+2ll*(n-4)%mod*(m-1)%mod*m%mod)%mod;
//cout<
swap(n,m);
ans=(ans+2ll*(m-2)%mod*m%mod)%mod; //边上的两个
if(n>2) ans=(ans+2ll*(n-2)%mod*(m-2)%mod*m%mod)%mod;
//长为1
ans=(ans+1ll*min(4ll,2ll*(n-2))*(m-1)%mod*m%mod)%mod;
if(n>4) ans=(ans+2ll*(n-4)%mod*(m-1)%mod*m%mod)%mod;
//cout<
LL num=((n-1)*(m-2)%mod+(m-1)*(n-2)%mod)%mod;
ans=(ans-num*4ll%mod+mod)%mod;
cout<<ans<<endl;
return 0;
}
这题题目坑了我,居然只有两种情况 我以为有n+1种情况…不难
#include
#include
#include
#include
#include
#include
#include
#include
#include
#include
#include
#define ls k<<1,l,mid
#define rs k<<1|1,mid+1,r
#define mp(x,y) make_pair(x,y)
#define r(x) read(x)
#define rrr(x,y,z) read(x);read(y);read(z)
#define FOR(i,l,r) for(int i=l;i<=r;i++)
using namespace std;
typedef long long LL;
typedef pair<int,int> pt;
const int N=1e6+5;
const int M=2e3+5;
const int INF=0x7fffffff;
const int mod=998244353;
const double eps=1e-8;
const double pi=acos(-1);
LL n,m;
int f[N];
template<class T>
inline void read(T &x)
{
char c; x=1;
while((c=getchar())<'0'||c>'9') if(c=='-') x=-1;
T res=c-'0';
while((c=getchar())>='0'&&c<='9') res=res*10+c-'0';
x*=res;
}
int main()
{
int a,b,x;
rrr(n,x,a); r(b);
double xx=x*1.0/100;
double ans=n*a*xx+n*b*(1-xx);
printf("%.2f\n",ans);
return 0;
}
还是分两种情况讨论,方法类似 就只说板子在x轴上吧
如果x0*x[ i ]>0说明 板子不可能挡住这个点,忽略就行,其他的点都有可能通过x轴上的板子阻挡箭。设点(x0,y0)与(x[ i ],y[ i ])连起来和x轴交于点p,那如果p在板子上就可以挡住此点了。 我们只需要挡住n-k个点,尺取就ok了。
#include
#include
#include
#include
#include
#include
#include
#include
#include
#include
#include
#define ls k<<1,l,mid
#define rs k<<1|1,mid+1,r
#define mp(x,y) make_pair(x,y)
#define r(x) read(x)
#define rrr(x,y,z) read(x);read(y);read(z)
#define FOR(i,l,r) for(int i=l;i<=r;i++)
using namespace std;
typedef long long LL;
typedef pair<int,int> pt;
const int N=1e6+5;
const int M=2e3+5;
const int INF=0x7fffffff;
const int mod=1e9+7;
const double eps=1e-8;
const double pi=acos(-1);
LL n,m;
double x[N],y[N];
double f[N];
template<class T>
inline void read(T &x)
{
char c; x=1;
while((c=getchar())<'0'||c>'9') if(c=='-') x=-1;
T res=c-'0';
while((c=getchar())>='0'&&c<='9') res=res*10+c-'0';
x*=res;
}
int main()
{
double x0,y0;
scanf("%lf%lf",&x0,&y0);
r(n); r(m);
FOR(i,1,n){
scanf("%lf%lf",&x[i],&y[i]);
}
m=n-m;
double ans1=2e10;
int cnt=0;
FOR(i,1,n){
if(y[i]*y0<0){
f[++cnt]=x0-y0*(x0-x[i])/(y0-y[i]);
}
}
sort(f+1,f+cnt+1);
//FOR(i,1,cnt){
// cout<
//}
//cout<
FOR(i,1,cnt-m+1){
ans1=min(f[i+m-1]-f[i],ans1);
}
//x板子
double ans2=2e10;
cnt=0;
FOR(i,1,n){
if(x[i]*x0<0){
f[++cnt]=y0-x0*(y0-y[i])/(x0-x[i]);
}
}
sort(f+1,f+cnt+1);
//FOR(i,1,cnt){
// cout<
//}
//cout<
FOR(i,1,cnt-m+1){
ans1=min(f[i+m-1]-f[i],ans1);
}
//cout<
if(ans1==2e10&&ans2==2e10) cout<<-1<<endl;
else printf("%.8f\n",min(ans1,ans2));
//y板子
return 0;
}
这题很水啊,想象成一个桶,哪个桶没有就是哪个…
#include
#include
#include
#include
#include
#include
#include
#include
#include
#include
#include
#define ls k<<1,l,mid
#define rs k<<1|1,mid+1,r
#define mp(x,y) make_pair(x,y)
#define r(x) read(x)
#define rrr(x,y,z) read(x);read(y);read(z)
#define FOR(i,l,r) for(int i=l;i<=r;i++)
using namespace std;
typedef long long LL;
typedef pair<int,int> pt;
const int N=1e6+5;
const int M=2e3+5;
const int INF=0x7fffffff;
const int mod=998244353;
const double eps=1e-8;
const double pi=acos(-1);
LL n,m;
int f[N];
template<class T>
inline void read(T &x)
{
char c; x=1;
while((c=getchar())<'0'||c>'9') if(c=='-') x=-1;
T res=c-'0';
while((c=getchar())>='0'&&c<='9') res=res*10+c-'0';
x*=res;
}
int main()
{
r(n);
FOR(i,1,n-1){
int a;
r(a);
f[a]++;
}
FOR(i,1,n){
if(f[i]==0){
cout<<i<<endl;
break;
}
}
return 0;
}
找n的因子个数只需要sqrt(n)次判断 就算是最大的n=1e12 开方之后是1e6
再开方 1e3 哪怕 还需要开1e3次方 也不会超时。
#include
#include
#include
#include
#include
#include
#include
#include
#include
#include
#include
#define ls k<<1,l,mid
#define rs k<<1|1,mid+1,r
#define mp(x,y) make_pair(x,y)
#define r(x) read(x)
#define rrr(x,y,z) read(x);read(y);read(z)
#define FOR(i,l,r) for(int i=l;i<=r;i++)
using namespace std;
typedef long long LL;
typedef pair<int,int> pt;
const int N=1e6+5;
const int M=2e3+5;
const int INF=0x7fffffff;
const int mod=998244353;
const double eps=1e-8;
const double pi=acos(-1);
LL n,m;
int f[N];
template<class T>
inline void read(T &x)
{
char c; x=1;
while((c=getchar())<'0'||c>'9') if(c=='-') x=-1;
T res=c-'0';
while((c=getchar())>='0'&&c<='9') res=res*10+c-'0';
x*=res;
}
int hhh(LL x)
{
int ans=0;
FOR(i,1,sqrt(x)){
if(x%i==0){
if(i==sqrt(x)) ans++;
else ans+=2;
}
}
return ans;
}
int main()
{
r(n);
LL now=n;
int ans=0;
while(1){
now=hhh(now);
if(now==2){
cout<<ans+1<<endl;
break;
}
//cout<
ans++;
}
return 0;
}
#include
#include
#include
#include
#include
#include
#include
#include
#include
#include
#include
#define ls k<<1,l,mid
#define rs k<<1|1,mid+1,r
#define mp(x,y) make_pair(x,y)
#define r(x) read(x)
#define rrr(x,y,z) read(x);read(y);read(z)
#define FOR(i,l,r) for(int i=l;i<=r;i++)
using namespace std;
typedef long long LL;
typedef pair<int,int> pt;
const int N=2e5+5;
const int M=2e3+5;
const int INF=0x7fffffff;
const int mod=998244353;
const double eps=1e-8;
const double pi=acos(-1);
LL n,m;
struct edge
{
int to,next;
}e[N];
int head[N<<1];
bool color[N];
char str[N];
int dad[N];
int num[N];
int gg[N];
int cnt;
vector<int> v;
template<class T>
inline void read(T &x)
{
char c; x=1;
while((c=getchar())<'0'||c>'9') if(c=='-') x=-1;
T res=c-'0';
while((c=getchar())>='0'&&c<='9') res=res*10+c-'0';
x*=res;
}
void add_edge(int x,int y)
{
e[++cnt].to=y;
e[cnt].next=head[x];
head[x]=cnt;
}
int seek(int k)
{
return dad[k]==k?k:dad[k]=seek(dad[k]);
}
int main()
{
r(n);
scanf("%s",str+1);
FOR(i,1,n){
dad[i]=i;
num[i]=1;
if(str[i]=='B'){
color[i]=1;
v.push_back(i);
}
else color[i]=0;
}
cnt=0;
FOR(i,1,n-1){
int a,b;
r(a); r(b);
add_edge(a,b);
add_edge(b,a);
if(color[a]==0&&color[b]==0){
int x=seek(a),y=seek(b);
if(x!=y){
dad[x]=y;
num[y]+=num[x];
}
}
}
LL ans=0;
for(int i=0;i<v.size();i++){
int now=v[i];
int cc=0;
LL sum=0;
for(int i=head[now];i;i=e[i].next){
int get=e[i].to;
if(color[get]==0){
int tmp=seek(get);
gg[++cc]=num[tmp];
sum+=num[tmp];
}
}
ans+=sum;
FOR(i,1,cc){
ans+=1ll*gg[i]*(sum-gg[i]);
sum-=gg[i];
}
}
cout<<ans<<endl;
return 0;
}
前缀和+二分 代码应该好懂
#include
#include
#include
#include
#include
#include
#include
#include
#include
#include
#include
#define ls k<<1,l,mid
#define rs k<<1|1,mid+1,r
#define mp(x,y) make_pair(x,y)
#define r(x) read(x)
#define rrr(x,y,z) read(x);read(y);read(z)
#define FOR(i,l,r) for(int i=l;i<=r;i++)
using namespace std;
typedef long long LL;
typedef pair<int,int> pt;
const int N=2e5+5;
const int M=2e3+5;
const int INF=0x7fffffff;
const int mod=998244353;
const double eps=1e-8;
const double pi=acos(-1);
LL n,m;
int f[N][26];
char s[N];
template<class T>
inline void read(T &x)
{
char c; x=1;
while((c=getchar())<'0'||c>'9') if(c=='-') x=-1;
T res=c-'0';
while((c=getchar())>='0'&&c<='9') res=res*10+c-'0';
x*=res;
}
int main()
{
r(n); r(m);
scanf("%s",s+1);
FOR(i,1,n){
FOR(j,0,25){
if(s[i]-'a'==j) f[i][j]=f[i-1][j]+1;
else f[i][j]=f[i-1][j];
}
}
int ans=INF;
FOR(i,1,n){
int l=i,r=n;
int res=INF;
while(l<=r){
int mid=(l+r)>>1;
bool flag=1;
FOR(j,0,25){
if(f[mid][j]-f[i-1][j]>=m){
flag=0;
break;
}
}
if(!flag){
res=mid;
r=mid-1;
}
else l=mid+1;
}
if(res!=INF) ans=min(res-i+1,ans);
}
if(ans==INF) cout<<-1<<endl;
else cout<<ans<<endl;
return 0;
}
和上一题一样…感觉水了 ,前缀和+二分
#include
#include
#include
#include
#include
#include
#include
#include
#include
#include
#include
#define ls k<<1,l,mid
#define rs k<<1|1,mid+1,r
#define mp(x,y) make_pair(x,y)
#define r(x) read(x)
#define rrr(x,y,z) read(x);read(y);read(z)
#define FOR(i,l,r) for(int i=l;i<=r;i++)
using namespace std;
typedef long long LL;
typedef pair<int,int> pt;
const int N=2e5+5;
const int M=2e3+5;
const int INF=0x7fffffff;
const int mod=998244353;
const double eps=1e-8;
const double pi=acos(-1);
LL n,m;
int f[N][2];
char s[N];
template<class T>
inline void read(T &x)
{
char c; x=1;
while((c=getchar())<'0'||c>'9') if(c=='-') x=-1;
T res=c-'0';
while((c=getchar())>='0'&&c<='9') res=res*10+c-'0';
x*=res;
}
int main()
{
r(n); r(m);
scanf("%s",s+1);
FOR(i,1,n){
if(s[i]=='1'){
f[i][1]=f[i-1][1]+1;
f[i][0]=f[i-1][0];
}
else{
f[i][0]=f[i-1][0]+1;
f[i][1]=f[i-1][1];
}
}
int ans1=0;
FOR(i,1,n){
int l=i,r=n;
int res=INF;
if(n-i+1<=ans1) break;
while(l<=r){
int mid=(l+r)>>1;
if(f[mid][1]-f[i-1][1]<=m){
l=mid+1;
res=mid;
}
else r=mid-1;
}
//cout<
if(res!=INF) ans1=max(res-i+1,ans1);
}
int ans2=0;
FOR(i,1,n){
int l=i,r=n;
int res=INF;
if(n-i+1<=ans2) break;
while(l<=r){
int mid=(l+r)>>1;
if(f[mid][0]-f[i-1][0]<=m){
l=mid+1;
res=mid;
}
else r=mid-1;
}
if(res!=INF) ans2=max(res-i+1,ans2);
}
cout<<max(ans1,ans2)<<endl;
return 0;
}
此题是补题。参考链接:https://www.cnblogs.com/SwiftAC/p/12260779.html
我当时有想过dp,但是就是不知道怎么转移 tcl tcl !
类似的字符串切割方法也可以学一下,挺方便的string s(str+i-3,str+i+1);
#include
#include
#include
#include
#include
#include
#include
#include
#include
#include
#include
#define ls k<<1,l,mid
#define rs k<<1|1,mid+1,r
#define mp(x,y) make_pair(x,y)
#define r(x) read(x)
#define rrr(x,y,z) read(x);read(y);read(z)
#define FOR(i,l,r) for(int i=l;i<=r;i++)
using namespace std;
typedef long long LL;
typedef pair<int,int> pt;
const int N=3e5+5;
const int M=2e3+5;
const int INF=0x7fffffff;
const int mod=998244353;
const double eps=1e-8;
const double pi=acos(-1);
LL n,m;
char str[N];
LL dp[N];
template<class T>
inline void read(T &x)
{
char c; x=1;
while((c=getchar())<'0'||c>'9') if(c=='-') x=-1;
T res=c-'0';
while((c=getchar())>='0'&&c<='9') res=res*10+c-'0';
x*=res;
}
int main()
{
r(n); LL a,b,c;
rrr(a,b,c);
scanf("%s",str+1);
FOR(i,1,n){
if(i>=4){
string s(str+i-3,str+i+1);
if(s=="nico"){
dp[i]=max(dp[i-4]+a,dp[i]);
}
else dp[i]=max(dp[i],dp[i-1]);
}
if(i>=6){
string s(str+i-5,str+i+1);
if(s=="niconi"){
dp[i]=max(dp[i-5]+b,dp[i]);
}
else dp[i]=max(dp[i],dp[i-1]);
}
if(i>=10){
string s(str+i-9,str+i+1);
if(s=="niconiconi"){
dp[i]=max(dp[i-10]+c,dp[i]);
}
else dp[i]=max(dp[i],dp[i-1]);
}
}
cout<<dp[n]<<endl;
return 0;
}
这题是个数学题,我不是数学手,搞了一天才搞懂
用到了 矩阵快速幂+欧拉降幂+快速幂
前两项特判就不说了
从第三项开始 都会呈现一定的规律
f( 3) =x1 * y1 * ab
f( 4) =x1 * y2 * a2b
f( 5) =x2 * y3 * a4
f( 6) =x3 * y5 * a7
设 xx yy aa 分别为x y a 的幂
再设g(1)=1 g(2)=1 ,当i>3时 g(i)=g(i-1)+g(i-2)
那么xx=g(n-2) ,yy=g(n-1) aa=g(n)-1 【n>3】
所以我们来一次矩阵快速幂就好了~
构造矩阵:
1 | 1 |
---|---|
0 | 0 |
但是斐波拉契数列到几十项就快爆了,我们一定要取模,但是怎么取了?
这里用到了欧拉降幂 假如我们要求ab ,现在我们用mod=1e9+7,题目也说了mod是个质数,当a
最后是个快速幂,我就不说了.
#include
#include
#include
#include
#include
#include
#include
#include
#include
#include
#include
#define ls k<<1,l,mid
#define rs k<<1|1,mid+1,r
#define mp(x,y) make_pair(x,y)
#define r(x) read(x)
#define rrr(x,y,z) read(x);read(y);read(z)
#define FOR(i,l,r) for(int i=l;i<=r;i++)
using namespace std;
typedef long long LL;
typedef pair<int,int> pt;
const int N=1e6+5;
const int M=2e3+5;
const int INF=0x7fffffff;
const int mod=1e9+7;
const double eps=1e-8;
const double pi=acos(-1);
LL n,m;
struct node
{
LL f[3][3];
}t;
template<class T>
inline void read(T &x)
{
char c; x=1;
while((c=getchar())<'0'||c>'9') if(c=='-') x=-1;
T res=c-'0';
while((c=getchar())>='0'&&c<='9') res=res*10+c-'0';
x*=res;
}
node mult(const node &a,const node &b)
{
node res;
FOR(i,1,2)
FOR(j,1,2){
res.f[i][j]=0;
FOR(k,1,2) res.f[i][j]=(res.f[i][j]+a.f[i][k]*b.f[k][j])%(mod-1);
}
return res;
}
LL qpow(LL a,LL p)
{
LL res=1;
while(p){
if(p&1) res=res*a%mod;
a=a*a%mod;
p>>=1;
}
return res;
}
int main()
{
LL x,y,a,b;
rrr(n,x,y); r(a); r(b);
x%=mod; y%=mod; a%=mod; b%=(mod-1);
if(n==1){cout<<x<<endl; return 0;}
else if(n==2){cout<<y<<endl; return 0;}
if(x==0||y==0||a==0){cout<<0<<endl; return 0;}
LL xx,yy,aa;
node now;
now.f[1][1]=now.f[2][2]=1; now.f[1][2]=now.f[2][1]=0;//单位矩阵
t.f[1][1]=t.f[1][2]=t.f[2][1]=1; t.f[2][2]=0; //构造出来的矩阵
n-=2;
while(n){
if(n&1) now=mult(now,t);
t=mult(t,t);
n>>=1;
}
aa=now.f[1][1]+now.f[1][2];
yy=now.f[2][1]+now.f[2][2];
yy=yy%(mod-1);
xx=(aa-yy+(mod-1))%(mod-1);
aa=(aa-1+(mod-1))%(mod-1);
//cout<
LL ans=qpow(x,xx)*qpow(y,yy)%mod*qpow(qpow(a,aa)%mod,b)%mod;
cout<<ans<<endl;
return 0;
}