【noip2013】d1解题报告
13年的题做的比较多,基本上博客里都有,表示今天一点干劲都提不上来qwq,啥都不~想~干~,表示d2t3更是直接不想做,d1水了210,货车运输翻车了,d2水了200,实在是不想做了……
……
t1:转圈游戏
一个裸的快速幂,套上去你就赢了
#include<iostream> #include<cstring> #include<cstdio> using namespace std; typedef long long lo; lo n,m,k,x,a,ans=1; int main() { scanf("%lld%lld%lld%lld",&n,&m,&k,&x); a=10; while(k)//先算出在模n意义下他走了几圈 { if(k&1) ans=((ans%n)*(a%n))%n; a=((a%n)*(a%n))%n; k>>=1; } ans=((ans%n)*(m%n)+x)%n;//乘上个m,完事 cout<<ans; }
t2:这个题之前做过,但理解的不透彻,这回算是好好理解了
首先我们可以稍加思考得出,要想使答案尽可能的小,就要保证ai-bi的绝对值尽可能的小
也就是说,a中第一大要对应b中第一大,第二大对应第二大……依次类推
所以说我们要求出a串每一个元素的对应元素在b串当中的位置,换句话说,我们想让b串变成一定的顺序
那么也就是说,b串从一个原下标有序的序列变成了原下标无序的序列,反过来也可以,就变成了让一个无序的序列变成了一个有序的序列。而且每次只能交换相邻的元素,这已经再明显不过了,这个题本质就是求逆序对!
#include<algorithm> #include<iostream> #include<cstring> #include<cstdio> using namespace std; struct in { int x,y; }ter[100010],es[100010]; int n; long long ans; bool cmp(in a,in b) { return a.x<b.x; } int a[100010],b[100010],c[100010],d[100010]; void m_st(int l,int r) { if(l==r) return; int mid=l+r>>1; m_st(l,mid),m_st(mid+1,r); int t1=l,t2=mid+1,t3=l-1; while(t1<=mid&&t2<=r) { if(c[t1]<=c[t2]) d[++t3]=c[t1++]; else d[++t3]=c[t2++],ans+=(mid-t1+1); } while(t1<=mid) d[++t3]=c[t1++]; while(t2<=r) d[++t3]=c[t2++]; for(int i=l;i<=r;i++) c[i]=d[i]; } int main() { scanf("%d",&n); for(int i=1;i<=n;i++) scanf("%d",&ter[i].x),ter[i].y=i;//记录下原来的数组下标 sort(ter+1,ter+1+n,cmp);//通过排序找到与自己对应的元素 for(int i=1;i<=n;i++) scanf("%d",&es[i].x),es[i].y=i; sort(es+1,es+1+n,cmp); for(int i=1;i<=n;i++) a[i]=ter[i].y;//a[i]表示现在下标为i的元素原来下标为a[i] for(int i=1;i<=n;i++) b[es[i].y]=i;//b[i]表示原来下标为i的元素现在下标在b[i] for(int i=1;i<=n;i++) c[i]=a[b[i]];//求出b串经过变化后要得到的序列 m_st(1,n);//归并排序求逆序对 cout<<ans-ans/99999997*99999997;//这里运用了int向下取整的小技巧来进行取模 }
t3:货车运输
这个题前两天做过,打的时候打次了,10分……
直接丢网址:http://www.cnblogs.com/Loi-dfkdsmbd/p/7750045.html